Обновлено требование от 06.04.2021:
У меня есть два массива объектов: arrX и arrY. Необходимо отсортировать объекты «arrY» так же, как и «arrX». Какой путь самый короткий или лучший?
Примечание: объекты, которые имеют тип, отличный от типов arrX, должны попасть в конец, т.е. "type: 'X'" здесь.
const arrX = [
{type: 'C', category: 'CAT2'},
{type: 'A', category: 'CAT1},
{type: 'B', category: 'CAT3'},
]
const arrY = [
{type: 'B', category: 'CAT3'},
{type: 'A', category: 'CAT1'},
{type: 'C', category: 'CAT2'},
{type: 'B', category: 'CAT3'},
{type: 'A', category: 'CAT1'},
{type: 'X', category: 'CAT4'},
{type: 'B', category: 'CAT2'},
{type: 'X', category: 'CAT4'},
{type: 'X', category: 'CAT5'},
{type: 'A', category: 'CAT1'},
{type: 'C', category: 'CAT2'},
]
Должно быть отсортировано как:
const arrX = [
{type: 'C', category: 'CAT2'},
{type: 'C', category: 'CAT2'},
{type: 'A', category: 'CAT1'},
{type: 'A', category: 'CAT1'},
{type: 'A', category: 'CAT1'},
{type: 'B', category: 'CAT3'},
{type: 'B', category: 'CAT3'},
{type: 'X', category: 'CAT4'},
{type: 'B', category: 'CAT2'},
{type: 'X', category: 'CAT4'},
{type: 'X', category: 'CAT5'},
]
Вы можете взять объект для заказа со значением по умолчанию для неизвестных типов.
const
arrX = [{ type: 'C' }, { type: 'A' }, { type: 'B' }],
arrY = [{ type: 'B' }, { type: 'A' }, { type: 'C' }, { type: 'B' }, { type: 'A' }, { type: 'X' }, { type: 'B' }, { type: 'X' }, { type: 'X' }, { type: 'A' }, { type: 'C' }],
order = Object.fromEntries(arrX.map(({ type }, i) => [type, i + 1]));
order.default = Number.MAX_VALUE;
arrY.sort((a, b) => (order[a.type] || order.default) - (order[b.type] || order.default));
console.log(arrY);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Я бы добавил то, что было бы сопоставимо вarrX
. Далее я добавилindex
кarrY
чтобы быть более различимым.
const addIndex = (list) => list.map((item, index) => ({ ...item, index }));
const targetIndex = (targets, element) => {
const found = targets.find((item) => item.type === element.type);
return found ? found.index : null;
};
const sortByType = (target, source) => {
const targetWithId = addIndex(target);
const sourceWithId = addIndex(source);
sourceWithId.sort((a, b) => {
const indexA = targetIndex(targetWithId, a);
const indexB = targetIndex(targetWithId, b);
if (indexA === indexB) {
return 0;
}
if (indexA === null) {
return 1;
}
if (indexB === null) {
return -1;
}
return indexA - indexB;
});
return sourceWithId;
};
result = sortByType(arrX, arrY);
что даст:
[
{ type: 'C', index: 2 },
{ type: 'C', index: 10 },
{ type: 'A', index: 1 },
{ type: 'A', index: 4 },
{ type: 'A', index: 9 },
{ type: 'B', index: 0 },
{ type: 'B', index: 3 },
{ type: 'B', index: 6 },
{ type: 'X', index: 5 },
{ type: 'X', index: 7 },
{ type: 'X', index: 8 }
]
index
ключ к обоим массивам, чтобы вы поняли, как работает сортировка. Это предложение позволяет вам расширяться, если у вас есть несколько свойств для сравнения, как вы предложили в комментарии к другому ответу.
arrY.sort
? evolutionxboxindexOf
голосованием (тот, который с простым сравнением indexOf), а не принятый). Было бы проще, если бы у вас былоconst arrX = [ "C", "A", "B" ]
. Sebastian Simon