如何根据另一个数组的顺序对对象数组进行排序?

TIM*_*MEX 13 javascript arrays sorting algorithm json

我有一个对象列表:

[ { id: 4, name:'alex' }, { id: 3, name:'jess' }, { id: 9, name:'...' }, { id: 1, name:'abc' } ]
Run Code Online (Sandbox Code Playgroud)

我有另一个正确的"订单"列表.

[ 3, 1, 9, 4]
Run Code Online (Sandbox Code Playgroud)

如何根据键"id"将第一个列表与第二个列表的顺序相匹配?结果应该是:

[ { id: 3, name:'jess' }, { id: 1, name:'abc' }, { id: 9, name:'...' }, { id: 4, name:'alex' } ]
Run Code Online (Sandbox Code Playgroud)

HCl*_*Clx 27

我介入了这个问题并用一个简单的方法解决了它 .sort

假设要排序的列表存储在变量中,needSort并且带有顺序的列表位于变量中order且两者都在同一范围内,您可以运行.sort如下:

needSort.sort(function(a,b){
  return order.indexOf(a.id) - order.indexOf(b.id);
});
Run Code Online (Sandbox Code Playgroud)

它对我有用,希望它有所帮助.

  • 你的3行可以压缩:`return order.indexOf(a.id)<order.indexOf(b.id)?-1:1;`JSFiddle:http://jsfiddle.net/zamnuts/guyjm0za/ (2认同)
  • 不将此标记为答案,就是在犯罪。 (2认同)
  • 我认为这个答案有问题,因为如果两个索引相等,排序函数不会返回“0”。这是病态的,因为只有当需要排序中的两个元素具有相同的“id”时才会发生这种情况。因此我会使用`return order.indexOf(a.id) - order.indexOf(b.id);` (2认同)

小智 7

嗯,简单的答案是,"对于一组数据这么小,任何比无限循环都要便宜的东西基本上都是不可察觉的." 但让我们试着回答这个"正确".

第二个数组中的顺序没有押韵或理由,它只是第一个数组主键上的外键列表(使用SQL术语).因此,将它们视为键,并且我们希望有效地查找这些键,哈希表(对象)可能会以最快的O(n)方式"排序"它,以某种方式(2*n实际上)假设第一个数组被调用objArray而第二个数组被称为keyArray:

// Create a temporary hash table to store the objects
var tempObj = {};
// Key each object by their respective id values
for(var i = 0; i < objArray.length; i++) {
    tempObj[objArray[i].id] = objArray[i];
}
// Rebuild the objArray based on the order listed in the keyArray
for(var i = 0; i < keyArray.length; i++) {
    objArray[i] = tempObj[keyArray[i]];
}
// Remove the temporary object (can't ``delete``)
tempObj = undefined;
Run Code Online (Sandbox Code Playgroud)

这应该做到这一点.我想不出任何不需要两遍的方法.(像这样一个接一个地,或者通过多次遍历数组并splice输出找到的元素,例如,对于向后排序的数据可能会花费很多.)


Fra*_*ans 7

我是如何解决同样的问题的

data = [{ id: 4, name:'alex' }, { id: 3, name:'jess' }, { id: 9, name:'...' }, { id: 1, name:'abc' } ];

sorted = [3, 1, 9, 4].map((i) => data.find((o) => o.id === i));
Run Code Online (Sandbox Code Playgroud)


Ern*_*ill 1

我认为您会发现的最好方法是使用 id 值作为属性名称将第一个列表的所有元素放入哈希中;然后通过迭代 id 列表、查找哈希中的每个对象并将其附加到列表中来构建第二个列表。