1

I have the following data:

var data = [[{x:"c", y:10}, {x:"a", y:20}, {x:"b", y:4}], [{x:"c", y:14}, {x:"a", y:22}, {x:"b", y:9}], [{x:"c", y:24}, {x:"a", y:65}, {x:"b", y:46}]]

I need to order the (x) element of each array (within the parent array) based on the value of the 'y' attributes from the last array element. The result would be:

[[{x:"c", y:10}, {x:"b", y:4}, {x:"a", y:20}], [{x:"c", y:14}, {x:"b", y:9}, {x:"a", y:22}], [{x:"c", y:24}, {x:"b", y:46}, {x:"a", y:65}]]

Any easy way to do that? Here's the global structure of the data:

var data = [[{x:"x_1", y:}, {x:"x_2", y:},.. {x:"x_N", y:}], [{x:"x_1", y:}, {x:"x_2", y:},.. {x:"x_N", y:}], [{x:"x_1", y:}, {x:"x_2", y:},.. {x:"x_N", y:}]]

I have an array of 3 arrays that each contains N hash tables.
I need to order the elements in all hash tables based on the values of the 'y' key from the last element (data[2]).

user393750
  • 13
  • 3
  • 2
    I don't quite see where the result is coming from? Can you explain it a little more (or show another example)? Why is the 1st element `{x:"c", y:10}, {x:"b", y:4}, {x:"a", y:20}`? Shouldn't it be `{x:"b", y:4}, {x:"c", y:10}, {x:"a", y:20}`? – gen_Eric Aug 02 '12 at 15:16
  • possible duplicate of [How to sort an array of javascript objects?](http://stackoverflow.com/questions/979256/how-to-sort-an-array-of-javascript-objects) -- please use the search before you ask a new question. – Felix Kling Aug 02 '12 at 15:44
  • Thanks Felix but I already came across that post. My data structure is an array of arrays of objects and I need to deduct the order of the objects elements based on the values of the object in the array element. – user393750 Aug 02 '12 at 17:58

3 Answers3

0
data.sort(function(a,b){return b.y-a.y});

http://www.w3schools.com/jsref/jsref_sort.asp

Colin Brock
  • 21,267
  • 9
  • 46
  • 61
Almir Sarajčić
  • 1,520
  • 3
  • 16
  • 19
0

I can't really see how you can archive what your demo result looks like but if you want what your text says this will do the job.

ASC

data.sort(function(a, b) {
    return b[b.length-1].y - a[a.length-1].y;
});

DESC

data.sort(function(a, b) {
    return a[a.length-1].y - b[b.length-1].y;
});
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
0

To get the expected result, you can use this algorithm. It is just a loop over all arrays in data, and sorts them with the common sort-by-function:

for (var i=0; i<data.length; i++)
    data[i].sort(function(a, b) {
        return (a.x < b.x) - (b.x < a.x);
    });

> JSON.stringify(data)
[[{"x":"c","y":10},{"x":"b","y":4},{"x":"a","y":20}],[{"x":"c","y":14},{"x":"b","y":9},{"x":"a","y":22}],[{"x":"c","y":24},{"x":"b","y":46},{"x":"a","y":65}]]

Note that it does not what you tried to describe, but sorts reverse by the x property.


EDIT: Now I got the task. Here's the algorithm:

// get the last element and sort it
var last = data[data.length-1];
last.sort(function(a,b){ return a.y-b.y; });

// get the sort order:
var order = last.map(function(o){ return o.x; }); // ["c", "b", "a"]

// now, reorder the previous arrays:
for (var i=0; i<data.length-1; i++) { // sic: loop condition is correct!
    // create a map for the items by their x property
    var hash = data[i].reduce(function(map, o){
        map[o.x] = o;
        return map;
    }, {});
    // create the new array by mapping the order
    data[i] = order.map(function(x) {
        return hash[x];
    });
};
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks Bergi. Changing your logic to: for (var i=0; i – user393750 Aug 02 '12 at 18:45
  • To sort by numbers, use `function(a,b){return b.y-a.y}`. However, in your example the expected result is *not* sorted by `y` - could you elaborate? – Bergi Aug 02 '12 at 18:52
  • Bergi, The trick is find the sorting order (on value of 'y' key) of the 'x' key of the last element (data[2]) THEN apply it to all other objects. Does that make sense? – user393750 Aug 02 '12 at 18:57