Javascript сортирует объекты по другому массиву [дубликаты]

Довольно старый вопрос, и если кто-то интересуется спецификациями ECMA по этому вопросу, вот ссылка

И нет никакого способа прямого доступа для переменных модуля (кроме для импортированных модулей):

Лексическая среда и среда Значения записи являются чисто спецификационными механизмами и не должны соответствовать какому-либо конкретному артефакту реализации ECMAScript. Программа ECMAScript не может напрямую обращаться к этим значениям или манипулировать ими.

blockquote>

-5
задан JonSnows 17 January 2019 в 08:36
поделиться

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; }

0
ответ дан Nina Scholz 17 January 2019 в 08:36
поделиться

В таком случае, когда вы хотите сортировать по нескольким уровням, вам нужно отсортировать их в порядке убывания важности внутри вашей функции сортировки.

В этом случае мы регулярно сортируем в тех случаях, когда оба элемента находятся в или не в массиве сортировки.

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);

Приведенный выше фрагмент кода можно расширить несколькими способами, но популярный подход заключается в разделении его на несколько этапов сортировки.

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);

Эту схему проще поддерживать, поскольку каждый шаг четко обозначен, а функции можно повторно использовать в других случаях сортировки. [1114 ]

Единственный недостаток этого паттерна заключается в том, что в конечном итоге вы повторяете список несколько раз, увеличивая время сортировки. Обычно это не проблема, но в очень больших списках это может быть важно.

Сортировать только по индексу массива

Поскольку комментарии указывают, что я неправильно прочитал вопрос, поэтому мои предыдущие два фрагмента сортировки не обязательно дают желаемый результат.

Эта версия сортирует только по индексу в массиве сортировки:

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);

0
ответ дан Emil S. Jørgensen 17 January 2019 в 08:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: