按另一个数组对 collection 进行排序

Sort a collection by another array

我有 collection 个名字:

[
  {last_name: "A", name: "James" }, 
  {last_name: "A", name: "Robert" }, 
  {last_name: "B", name: "Tim"}, 
  {last_name: "B", name: "Bob" },
  {last_name: "C", name: "Ricky Ticky" }
]

然后我有一个数组,里面有每个 last_name,按照特定的顺序:

["B", "C", "A"]

如何在第二个数组中按 last_names 的顺序对 collection 进行排序?

我试过的:

目前我的最佳解决方案是创建一个新数组,然后遍历我的 collection 个名称,推送所有与排序数组的第一个索引 ("B") 匹配的元素,然后是第二个索引 ("C"),最后是 "A"。看起来很冗长,或者 underscore.js 有更好的方法。

使用 Underscore 的 sortBy 函数,使您能够根据数组元素的任意特征进行排序:

var people = [
  {last_name: "A", name: "James" }, 
  {last_name: "A", name: "Robert" }, 
  {last_name: "B", name: "Tim"}, 
  {last_name: "B", name: "Bob" },
  {last_name: "C", name: "Ricky Ticky" }
];

var lastNameOrder = ["B", "C", "A"];

var sortedPeople = _.sortBy(people, function(person) {
  return lastNameOrder.indexOf(person.last_name);
})

console.log(sortedPeople);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

这可以通过 Array.sort() 相当简单地完成。

function sortNames(names, order) {
  return names.sort(function(a,b) {
    if (order.indexOf(a.last_name) > order.indexOf(b.last_name)) return 1;
    return 0;
  });
}

Array.prototype.sort() 将通过一次比较两个值来对数组进行排序。如果你 return 1,b 在 a 之前; -1,a在b之前;零是没有变化。

更多信息请见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

已编辑:因为严重失败

但它仍然没有对名称进行排序,因为我看不出有任何理由不这样做

var people = [
  {last_name: "A", name: "James" }, 
  {last_name: "A", name: "Robert" }, 
  {last_name: "B", name: "Tim"}, 
  {last_name: "B", name: "Bob" },
  {last_name: "C", name: "Ricky Ticky" }
];

var lastNameOrder = ["B", "C", "A"];

var sortedPeople = people.sort(function(person1,person2){
  var lna =  lastNameOrder.indexOf(person1.last_name);
  var lnb =  lastNameOrder.indexOf(person2.last_name);

  if(lna === lnb){
    return (person1.name < person2.name) ? -1 : 
           (person1.name > person2.name) ?  1 : 0;
  } else {
    return lna-lnb;
  }
})