简体   繁体   English

d3.js:排序嵌套数组

[英]d3.js: sort nested arrays

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. 我想排序数组prob ,然后相应地重新排列name ,以保持关系。

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! 谢谢!

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. 如果将nameprob的数组转换为对象以保留每个名称与概率之间的链接,则最简单。 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. 如果您不使用d3,请将d3.descending替换为标准降序排序功能。

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: 这里有一个解决方案:我们可以pairs存储namesprob并同时对这两个值进行排序,然后我们将这些名称和probs分配给主对象:

 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) 

Refactoring Emeeus answer 重构Emeeus答案

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM