3

I have mutlriple objects called stations. Each station has a property called money.

stations[0].money = 2000
stations[1].money = 500
stations[2].money = 1200
stations[3].money = 2200

I want to create an array of stations indexes (0,1,2 and 3 in this example) but sorted by ammount of money each station has ascending by money. So I want to have:

var moneyArray = [1, 2, 0, 3]

what is the most elegant way to do it?

Nickolay
  • 31,095
  • 13
  • 107
  • 185
Kalreg
  • 982
  • 1
  • 13
  • 27

3 Answers3

3

You can start with a normal array of indices (loop-generated, preferably) and sort that by the value of the object at the respective index in your stations array:

[0, 1, 2, 3].sort(function(ai, bi) {
    return stations[ai].money - stations[bi].money;
})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • You beat me. The array of indices can be generated with `stations.map((_,i) => i)` – Oriol Mar 26 '16 at 19:28
  • Or maybe `Object.keys(stations).sort`? – Nickolay Mar 26 '16 at 19:36
  • definately best solution for me :) – Kalreg Mar 26 '16 at 19:36
  • @Nickolay That would include non-integer keys (if any), to ignore them I recommend using only array methods. `Array.from(stations.keys())` is a short polyfillable alternative. – Oriol Mar 26 '16 at 19:44
  • @Nickolay: Nice idea (concise especially), but don't forget that will get you strings not integers. – Bergi Mar 26 '16 at 20:23
  • Yeah, I didn't want to focus my answer on the question "*What's the best way to create the sequence `0…n-1` in JS?*", as that's a different topic. And probably a duplicate of a question we already have somewhere - had I found it, I would've linked it. Anyone? – Bergi Mar 26 '16 at 20:25
  • There's no elegant way to implement [range(0,n) in JS](http://stackoverflow.com/q/3895478/1026), but the question requires "an array of stations indexes". Whether (1)you need them as numbers/strings, (2)the array can have non-array keys, and whether (3)it can be sparse -- that all depends on the specific requirements. I think that "1)strings/ 2)no /3)yes" (that's when Object.keys shines) is as valid assumption as any. – Nickolay Mar 27 '16 at 02:58
1

You may have a look here: Sorting with map

// the array to be sorted
var stations = [
        { money: 2000 },
        { money: 500 },
        { money: 1200 },
        { money: 2200 },
    ];

// temporary array holds objects with position and sort-value
var mapped = stations.map(function (el, i) {
    return { index: i, value: el.money };
})

// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
    return a.value - b.value;
});

// container for the resulting order
var result = mapped.map(function (el) {
    return stations[el.index];
});

// get the wanted keys
var keys = mapped.map(function (el) {
    return el.index;
});

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(keys, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

By using a Temp variable you can do it this way. Else if you can afford to modify the main data then the temp variable can be eliminated.

var stations = [{money :2000},{money :500},{money :1200},{money :2200}]

var tempArray = stations.slice();

tempArray.forEach(function (value, i) {
    value.index = i;
});

tempArray.sort(function(a, b){return a.money-b.money});

var finalResult = tempArray.map(function(a) {return a.index;});

document.write(JSON.stringify(finalResult));
Rajshekar Reddy
  • 18,647
  • 3
  • 40
  • 59