bits
bits

Reputation: 8340

Sorting only one property inside an array based on another property

I have a Javascript array that has 2 properties id, sortedPosition.

I want to kind of fake sort the array based on id, and modify sortedPosition such that it reflects the sorted position of the object within that array.

For example:

Input array:

[
    {
        "id" : 34,
        "sortedPosition" : 2
    }, {
        "id" : 3,
        "sortedPosition" : 1
    }, {

        "id" : 344,
        "sortedPosition" : 0
    }
]

Output array:

[
    {
        "id" : 34,
        "sortedPosition" : 1
    }, {
        "id" : 3,
        "sortedPosition" : 0
    }, {
        "id" : 344,
        "sortedPosition" : 2
    }
]

I came upon a solution which looks pretty bad, it involves 2 extra copies of deepCloned arrays, and it doesn't seem right. There has to be a more elegant solution.

Thanks for any help.

Upvotes: 2

Views: 41

Answers (2)

Bergi
Bergi

Reputation: 664444

I came upon a solution which looks pretty bad, it involves 2 extra copies of deepCloned arrays

A shallow copy of the array should be enough:

arr.slice() // create new array with the same objects
 .sort(function(a,b){return a.id-b.id;}) // sort that (leave original untouched)
 .forEach(function(o,i){o.sortedPosition = i;}); // update the objects

Upvotes: 3

Pointy
Pointy

Reputation: 413720

Sort the array and then update the position.

array.sort(function(a1, a2) {
  return a1.id - a2.id;
});

array.forEach(function(v, i) {
  v.sortedPosition = i;
});

edit if you just want to set the sorted position, you can do something like this:

var t = array.map(function(v) {
  return { v: v }
});
t.sort(function(v1, v2) { return v1.v.id - v2.v.id; });
t.forEach(function(v, i) { v.v.sortedPosition = i; });

That makes a new array with references to the objects in the original array, then sorts it, then fixes up the position properties. The ordering of the original array is unaffected. The pass to make a new array won't be very expensive; it's not really a "deep copy" at all.

Upvotes: 0

Related Questions