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

IT技术 javascript arrays json algorithm sorting
2021-01-27 21:36:23

我有一个对象列表:

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

我有另一个带有正确“顺序”的列表。

[ 3, 1, 9, 4]

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

[ { id: 3, name:'jess' }, { id: 1, name:'abc' }, { id: 9, name:'...' }, { id: 4, name:'alex' } ]
6个回答

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

假设您要排序的列表存储在变量中,needSort并且具有顺序的列表在变量中order并且两者都在同一范围内,您可以.sort像这样运行

needSort.sort(function(a,b){
  return order.indexOf(a.id) - order.indexOf(b.id);
});

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

我认为这个答案有问题,因为0如果两个索引相等,则排序函数不会返回这是病态的,因为只有当需要排序中的两个元素具有相同的id. 因此我会使用return order.indexOf(a.id) - order.indexOf(b.id);
2021-03-17 21:36:23
你的 3 行可以被压缩:return order.indexOf(a.id) < order.indexOf(b.id) ? -1 : 1;JSFiddle: jsfiddle.net/zamnuts/guyjm0za
2021-03-23 21:36:23
嘿,如果两个数组的长度,即要排序的实际数组和 order 数组的长度不同,这会起作用吗?而且,在这种情况下,如果我们需要进一步按 id 对其进行排序,如果 2 个 id 相同,我们该怎么做。
2021-03-24 21:36:23
不将此标记为答案,就是在犯罪。
2021-04-04 21:36:23
感谢您的建议,我已将其添加到答案中。
2021-04-07 21:36:23

我如何解决几乎相同的问题

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));
真的。通过附加类似的东西可以轻松修复.filter(o => o),具体取决于您要查找的内容。
2021-04-05 21:36:23
此代码假定 中[3, 1, 9, 4]的每个元素都有一个元素data如果数据仅包含一个子集,则排序列表可能包含undefined元素。
2021-04-12 21:36:23

嗯,简单的答案是,“对于这么小的一组数据,任何比无限循环成本更低的东西基本上都不会引起注意。” 但让我们试着回答这个“对”。

第二个数组中的顺序没有韵律或理由,它只是第一个数组主键上的外键列表(使用 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;

那应该这样做。我想不出任何不需要两次通过的方法。(一个接一个,像这样,或者通过数组多次传递并splice取出找到的元素,例如,使用向后排序的数据可能会变得昂贵。)

您可以通过将 objArray.length 移动到 var 来进一步加快速度,这样就不会每次都对其进行评估。(但你已经知道了:) 这从我那里得到了 +1
2021-03-20 21:36:23

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

将列表变成一个对象,而不是order = [3, 1, 9, 4]您将拥有order = { 3:0, 1:1, 9:2, 4:3},然后执行以下操作

function ( order, objects ){
     ordered_objects = []
     for( var i in objects ){
           object = objects[i]
           ordered_objects[ order[ object.id ] ] = object
     }
     return ordered_objects
}
我认为你缺少s... object = object[i]
2021-04-02 21:36:23