【问题标题】:Javascript sort an objects by another array [duplicate]Javascript按另一个数组对对象进行排序[重复]
【发布时间】:2019-06-11 09:55:55
【问题描述】:

我有两个数组。

itemsArray = 
[
{ id: 8, name: 'o'},
{ id: 7, name: 'g'},
{ id: 6, name: 'a'},
{ id: 5, name: 'k'},
{ id: 4, name: 'c'}
]

sortArray = [4,5]

如何按 sortArray(lodash 或 pure)对 itemsArray 进行排序,但我想这样做:

newArray = 
[
{ id: 4, name: 'c'},
{ id: 5, name: 'k'},
{ id: 8, name: 'o'},
{ id: 7, name: 'g'},
{ id: 6, name: 'a'}
]

【问题讨论】:

标签: javascript arrays sorting object


【解决方案1】:

在这种情况下,您希望在多个级别上进行排序,您需要在排序函数中按重要性降序对它们进行排序。

在这种情况下,我们会定期对两个元素都在或不在排序数组中的情况进行排序。

var itemsArray = [
    { id: 8, name: 'o' },
    { id: 7, name: 'g' },
    { id: 6, name: 'a' },
    { id: 5, name: 'k' },
    { id: 4, name: 'c' }
];
var sortArray = [4, 5];
var sortedItemsArray = itemsArray.sort(function (a, b) {
    if (sortArray.includes(a.id) == sortArray.includes(b.id)) { //both or neither are in sort array
        return b.id - a.id;
    }
    else if (sortArray.includes(a.id)) { //only a in sort array
        return -1;
    }
    else { //only b in sort array
        return 1;
    }
});
console.log(sortedItemsArray);

上面的 sn-p 可以通过多种方式展开,但一种流行的方法是将其分成几个排序步骤。

var itemsArray = [
    { id: 8, name: 'o' },
    { id: 7, name: 'g' },
    { id: 6, name: 'a' },
    { id: 5, name: 'k' },
    { id: 4, name: 'c' }
];
var sortArray = [4, 5];
function sortId(a, b) {
    return b.id - a.id;
}
function sortIdByList(a, b) {
    if (sortArray.includes(a.id)) {
        return -1;
    }
    if (sortArray.includes(b.id)) {
        return 1;
    }
    return 0;
}
//TEST
var sortedItemsArray = itemsArray
    .sort(sortId)
    .sort(sortIdByList);
console.log(sortedItemsArray);

这种模式更容易维护,因为每个步骤都有明确的标签,并且功能可以在其他排序情况下重复使用。

这种模式的唯一缺点是您最终会多次迭代列表,从而增加了排序时间。通常这不是问题,但在非常大的列表中,这可能很重要。

仅按数组索引排序

正如 cmets 指出的那样,我误读了这个问题,所以我之前的两个排序 sn-ps 不一定会给出预期的结果。

此版本仅按排序数组中的 id 索引排序:

var itemsArray = [
    { id: 8, name: 'o' },
    { id: 7, name: 'g' },
    { id: 6, name: 'a' },
    { id: 5, name: 'k' },
    { id: 4, name: 'c' }
];
var sortArray = [4, 5];
//TEST
var sortedItemsArray = itemsArray
    .sort(function (a, b) {
    //Calculate index value of a
    var A = sortArray.indexOf(a.id);
    if (A == -1) {
        A = sortArray.length;
    }
    //Calculate index value of b
    var B = sortArray.indexOf(b.id);
    if (B == -1) {
        B = sortArray.length;
    }
    //Return comparison
    return A - B;
});
console.log(sortedItemsArray);

【讨论】:

  • 这似乎不起作用。此外,您不应该回答明显重复的问题。
  • 请注意,您比较返回 b.id - a.id; 而不是数组中 id 的索引,这可能会有所不同。当sortIdsArr = [7,3,9]
【解决方案2】:

您可以将数组的索引用于保持相对位置,并将具有负索引的特殊项放在顶部进行排序。

然后通过获取索引对数组进行排序。

var array = [{ id: 8, name: 'o' }, { id: 7, name: 'g' }, { id: 6, name: 'a' }, { id: 5, name: 'k' }, { id: 4, name: 'c' }],
    sortArray = [4, 5],
    indices = array.reduce((r, { id }, i) => (r[id] = i, r), {});
    
sortArray.forEach((id, i, { length }) => indices[id] = i - length);

array.sort(({ id: a }, { id: b }) => indices[a] - indices[b]);

console.log(array);
console.log(indices);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 您刚刚用duplicate answer by yourself 回答了一个重复的问题。干燥。
  • @str,不完全,另一个答案有所有新位置,但这里的部分项目应该相对保留。
最近更新 更多