0

I want to sort an array of objects based upon any of those object properties. But I want the original array left unchanged. Instead, I want to save the sort order of indexes in a separate array.

var source = [
  {"a": 2, "b": 8, "c": 9},
  {"a": 4, "b": 3, "c": 7},  
  {"a": 1, "b": 0, "c": 6}
]

var sortedIndexes;

SomeSortOfSortMethod("a", "asc");

// result of sortedIndexes containing indexes to source array:
// [2, 0, 1] 

Any ideas how to do this? I can't use the built in javascript sort method because it changes source. I need to just capture what the sort would be and save that order as indexes to the source arry.

1
  • 3
    Copy initial array and operate copied array ;) Commented Feb 6, 2016 at 3:08

2 Answers 2

1
var source = [
      {"a": 2, "b": 8, "c": 9},
      {"a": 4, "b": 3, "c": 7},  
      {"a": 1, "b": 0, "c": 6}
    ];

var orderedCopyArray = _.sortBy(source, "a");

// Defualt ascending
console.log(JSON.stringify(orderedCopyArray));

// Descending
console.log(JSON.stringify(orderedCopyArray.reverse()));

var indexesArray = [], leng = source.length;

// Descending array ordered
var reverse = orderedCopyArray.reverse();

// Get index
for(var i=0; i < leng; i++){
  var obj1 = reverse[i]; 
  for(var j=0; j < leng; j++){
    var obj2 = source[j];
    if(_.isEqual(obj1, obj2)){
      indexesArray.push(j);
      break;
    }
  }
}

console.log(indexesArray); //[2, 0, 1]
Sign up to request clarification or add additional context in comments.

11 Comments

That should be a comment, not an answer.
Mmmmm honestly in my opinion this is a valid alternative answer. Using external library is most of the times better than implement on your own a new one.
Because otherwise questions will be "answered" with suggestions to use libraries and not real answers. Imagine asking a DOM question and just getting answers like "use jQuery", "use Dojo", "use prototype.js"…
Ok, I added an example how do it wi UnderscoreJS
I agree RobG that questions can't be answered by just saying use such and such library. But I do appreciate ronIDX taking the time to explain the process through.
|
1

Make deep copy of initial array using array.map() and clone and apply sorting function over copied array.

The map() method creates a new array with the results of calling a provided function on every element in this array.

The sort() method sorts the elements of an array in place and returns the array.

Try this:

var source = [{
  "a": 2,
  "b": 8,
  "c": 9
}, {
  "a": 4,
  "b": 3,
  "c": 7
}, {
  "a": 1,
  "b": 0,
  "c": 6
}];

function clone(obj) {
  if (null == obj || "object" != typeof obj) return obj;
  var copy = obj.constructor();
  for (var attr in obj) {
    if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
  }
  return copy;
}
var temp = source.map(function(arr) {
  return clone(arr); //clone will make deep copy of the object
});
source[0].a = 50; //update the value from source object, it will not update `temp` array 
temp.sort(function(a, b) {
  return a.a - b.a; // `.a` will be the `key` to be sorted
});
snippet.log(JSON.stringify(temp));
snippet.log(JSON.stringify(source));
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

2 Comments

map doesn't make a "deep" copy, var temp = source.slice() gives the same result and is less to type.
@RobG, I got that wrong ;) Have updated the code with helper clone and added some comments too! I hope I am correct this time. Thank you for correcting me..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.