按特定顺序对JavaScript对象数组进行排序(使用现有函数)

按特定顺序对JavaScript对象数组进行排序(使用现有函数),javascript,jquery,arrays,sorting,underscore.js,Javascript,Jquery,Arrays,Sorting,Underscore.js,给定一组对象: { key: "a", value: 42 }, { key: "d", value: 28 }, { key: "c", value: 92 }, { key: "b", value: 87 } 是否有ECMAScript函数或第三方JavaScript库,允许您在一行/函数调用中排序--第一个对象数组,以匹配第二个数组中指定的键的顺序,从而得到以下结果: { key: "c", value: 92

给定一组对象:

{ key: "a", value: 42 }, { key: "d", value: 28 }, { key: "c", value: 92 }, { key: "b", value: 87 } 是否有ECMAScript函数或第三方JavaScript库,允许您在一行/函数调用中排序--第一个对象数组,以匹配第二个数组中指定的键的顺序,从而得到以下结果:

{ key: "c", value: 92 }, { key: "a", value: 42 }, { key: "b", value: 87 }, { key: "d", value: 28 } { 键:“c”, 价值:92 }, { 钥匙:“a”, 价值:42 }, { 钥匙:“b”, 价值:87 }, { 钥匙:“d”, 价值:28 } 提供函数或算法的其他问题:

类似/相关问题:


只需使用
indexOf
将钥匙转换为正确的顺序:

var order = ["c", "a", "b", "d"];
_.sortBy(arr, function(obj){ 
    return _.indexOf(order, obj.key);
});

如果有很多键,那么最好从数组中生成哈希映射,如:

var order = ["c", "a", "b", "d"];
var orderMap = {};
_.each(order, function(i) { orderMap[i] = _.indexOf(order, i); });

这使得键排序查找时间恒定,而不是O(n)。()

我不能说这是最有效的方法,但您可以将每个对象的
键用作另一个对象中属性的键。然后简单地通过这些键访问它们

for (x = 0; x < objn.length; x++) {
    newobj[objn[x].key] = objn[x];
}
objn = [];
for (x = 0; x < keys.length; x++) {
    objn.push(newobj[keys[x]]);
}
console.log(objn);
for(x=0;x

到目前为止,我们提供了非常好的答案。我认为以下可能也是普通JS中的替代解决方案:

var arr = arr.sort(function(a,b) {
    return order.indexOf( a.key ) - order.indexOf( b.key );
    //for the sake of recent versions of Google Chrome use:
    //return a.key.charCodeAt(0) > b.key.charCodeAt(0); or return a.key.charCodeAt(0) - b.key.charCodeAt(0);
});
var-arr=[
{
钥匙:“a”,
价值:42
},
{
钥匙:“d”,
价值:28
},
{
键:“c”,
价值:92
},
{
钥匙:“b”,
价值:87
}
];
变量顺序=[“c”、“a”、“b”、“d”];
log('Original:',JSON.stringify(arr));
var arr=arr.sort(函数(a,b){
返回订单.indexOf(a.key)-订单.indexOf(b.key);
});
log('Ordered:',JSON.stringify(arr))
const obj=[
{
钥匙:“a”,
价值:42
},
{
钥匙:“d”,
价值:28
},
{
键:“c”,
价值:92
},
{
钥匙:“b”,
价值:87
}
]
常数排序表=[“c”、“a”、“b”、“d”];
const sortedObj=对象排序((a,b)=>{
返回(
sortList.indexOf(a.key)-sortList.indexOf(b.key)
);
});

控制台日志(sortedObj)您是否尝试过使用array.sort(function())和插入排序/选择排序的组合?或者你只需要一个第三方解决方案?我在发布这篇文章后发现了几个其他问题和解决方案,并更新了这个问题。所以现在的目标是找到一些现成的东西,而不是重新实现它。。。这是一个购物问题,因此将被关闭。我很困惑为什么这个问题被投票关闭。如果有一个本地的方式来做,有人会在其他问题中提到它。真棒的答案。很简单,我喜欢这个。在现有库中找到它仍然是一个很好的选择,因为它是一个单一的函数。我使用的是CoffeeScript,所以这实际上是一个很好的一行:
arr=\u0.sortBy arr,(obj)->\u0.indexOf order,obj.key
@mkopala您可以使用0.mixin()添加自己的函数来下划线。这个示例对我来说不是很清楚。下面是一个额外的示例,让我明白了这一点。下面是一个支持将未包含在
顺序中的数组项重新排序到排序后的数组后面的示例。在您的版本中,
顺序
数组中未包含的项被放置在排序数组的前面。在Chrome 60中,我无法直接从排序回调返回布尔值,而是需要返回
-1
0
1
@bardiharbow,返回一个.key.charCodeAt(0)如何>b.key.charCodeAt(0)
返回a.key.charCodeAt(0)-b.key.charCodeAt(0)
?我很确定这应该是
order.indexOf(a.key)-order.indexOf(b.key)
,而不是布尔比较运算符。
var arr = arr.sort(function(a,b) {
    return order.indexOf( a.key ) - order.indexOf( b.key );
    //for the sake of recent versions of Google Chrome use:
    //return a.key.charCodeAt(0) > b.key.charCodeAt(0); or return a.key.charCodeAt(0) - b.key.charCodeAt(0);
});
// create hash map el.key -> index, to help us with direct access, avoid searching
const hashMap = arr.reduce((acc, el, index) => { acc[el.id] = el; return acc }, {})

// finally, map the ids to the final result
const ids.map(id => hashMap[id])