Reputation: 3593
How can I sort the nested arrays of an array like the one below please? I would like to sort array prob
and then rearrange name
accordingly so that relationship is maintained.
var records = [
{ num: 1, name: ["Sam", "Amy", "John"], prob: [0.3, 0.2, 0.5]},
{ num: 2, name: ["Nick", "Carol", "Sam"], prob: [0.5, 0.03, 0.47] },
{ num: 3, name: ["Ken", "Eric", "Ely"], prob: [0.1, 0.3, 0.6] },
{ num: 4, name: ["Amy", "Sam", "John"], prob: [0.6, 0.3, 0.1] },
{ num: 5, name: ["Chris", "Donna", "Jeff"], prob: [0.25, 0.55, 0.2] }
]
I would like to end-up with:
var records = [
{ num: 1, name: ["John", "Sam", "Amy"], prob: [0.5, 0.3, 0.2]},
{ num: 2, name: ["Nick", "Sam", "Carol"], prob: [0.5, 0.47, 0.03] },
{ num: 3, name: ["Ely", "Eric", "Ken"], prob: [0.6, 0.3, 0.1] },
{ num: 4, name: ["Amy", "Sam", "John"], prob: [0.6, 0.3, 0.1] },
{ num: 5, name: ["Donna", "Chris", "Jeff"], prob: [0.55, 0.25, 0.2] }
]
Thanks!
Upvotes: 1
Views: 610
Reputation: 9530
It's easiest if you turn your arrays of name
s and prob
s into objects to preserve the links between each name and the probability. The object's properties can then be sorted as if they were an array using a custom sort function.
records.forEach( function (d) {
var temp = {};
// create objects with key <name> and value <prob>
// (this makes the assumption that prob values may not be unique, but names are)
d.name.forEach( function(e,i) {
temp[e] = d.prob[i];
})
// get an array of the object keys (the name), and sort them by the object values
// (the corresponding prob), descending. Replace the existing `name` array with this.
d.name = Object.keys(temp).sort(function(a, b){
return temp[b] - temp[a];
});
// sort the prob values in descending order (with d3.descending, since you mentioned d3)
d.prob = d.prob.sort(function(a,b){ return b - a; });
});
If you aren't using d3, replace d3.descending
with the standard descending sort function.
Upvotes: 1
Reputation: 5260
Here a solution: we could store names
and prob
in pairs
and sorting both values at the same time, then we assign that names and probs sorted to the main object:
var records = [
{ num: 1, name: ["Sam", "Amy", "John"], prob: [0.3, 0.2, 0.5]},
{ num: 2, name: ["Nick", "Carol", "Sam"], prob: [0.5, 0.03, 0.47] },
{ num: 3, name: ["Ken", "Eric", "Ely"], prob: [0.1, 0.3, 0.6] },
{ num: 4, name: ["Amy", "Sam", "John"], prob: [0.6, 0.3, 0.1] },
{ num: 5, name: ["Chris", "Donna", "Jeff"], prob: [0.25, 0.55, 0.2] }
];
var pairs = records.map((e,i)=>
e.name.map((e2,i2)=>[e2,records[i].prob[i2]]).sort((a,b)=>b[1]-a[1])
);
records.map((e, i) => {
e.name = pairs[i].map(o => o[0])
e.prob = pairs[i].map(o => o[1])
})
console.log(records)
Upvotes: 1
Reputation: 28838
Refactoring Emeeus answer
var records = [
{ num: 1, name: ["Sam", "Amy", "John"], prob: [0.3, 0.2, 0.5]},
{ num: 2, name: ["Nick", "Carol", "Sam"], prob: [0.5, 0.03, 0.47] },
{ num: 3, name: ["Ken", "Eric", "Ely"], prob: [0.1, 0.3, 0.6] },
{ num: 4, name: ["Amy", "Sam", "John"], prob: [0.6, 0.3, 0.1] },
{ num: 5, name: ["Chris", "Donna", "Jeff"], prob: [0.25, 0.55, 0.2] }
];
records.forEach((e, i) => {
var el = e.name.map((e2,i2)=>[e2,e.prob[i2]]);
el.sort((a, b) => b[1] - a[1]);
e.name = el.map(o => o[0]);
e.prob = el.map(o => o[1]);
});
console.log(records);
Upvotes: 1