1

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!

5
  • combine the elements of name and prop in an array of objects with name and prop properties. sort this array by prop, create the name and prop array from this sorted array of objects Commented Sep 5, 2018 at 14:21
  • 2
    how is this d3.js related? Commented Sep 5, 2018 at 14:23
  • Can you clarify "name accordingly so that relationship is maintained.". How are you sorting the names array (in what order). Commented Sep 5, 2018 at 14:26
  • array of objects, zip the arrays name and prob Commented Sep 5, 2018 at 14:36
  • 1
    What have you found in your research? Commented Sep 5, 2018 at 15:48

3 Answers 3

1

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)

Sign up to request clarification or add additional context in comments.

7 Comments

what is the need to keep the intermediate results of pairs?
@rioV8 to sort both values at the same time
No. Just sort el. indentation helps readability. and ; are also helpful, construct el with .map()
el is an array you can sort, === e you use in pairs.forEach
another good point @rioV8, thanks. I was too focused on the main logic
|
1

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);

Comments

1

It's easiest if you turn your arrays of names and probs 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.

3 Comments

using 2 different sorting methods and both hard coded is waiting for a very hard to track bug if the code is modified. Use the same sorting function.
d3.descending performs the same sorting function as a standard numeric sort.
thanks a lot everyone, this is what i ended up with, pretty much what rioV8 and Emmeus proposed: var out = []; for (var i=0; i<records.length; i++) { t = d3.zip(records[i].name, records[i].prob); t.sort(function (a, b) { return b[1] - a[1]; }); var name = t.map(function (d, i) { return d[0] }); var prob = t.map(function (d, i) { return d[1] }); out.push({ num: records[i].num, name: name, prob: prob, }); }

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.