#javascript #arrays #typescript #sorting
#javascript #массивы #typescript #сортировка
Вопрос:
У меня есть следующее
let arr = [
{ id: 1, referenceId: 1, type: "normal", name: "a" },
{ id: 2, referenceId: 1, type: "normal", name: "b" },
{ id: 3, referenceId: 3, type: "chat", name: "c" },
{ id: 4, referenceId: 4, type: "normal", name: "d" },
{ id: 5, referenceId: 5, type: "chat", name: "e" },
{ id: 6, referenceId: 3, type: "chat", name: "f" }
];
Я хочу, чтобы вывод выглядел следующим образом :
[
{ id: 1, referenceId: 1, type: "normal", name: "a" },
{ id: 2, referenceId: 1, type: "normal", name: "b" },
{ id: 4, referenceId: 4, type: "normal", name: "d" },
{ id: 5, referenceId: 5, type: "chat", name: "e" },
{ id: 6, referenceId: 3, type: "chat", name: "f" }
];
Я хочу отсортировать, если type === «чат», попробуйте так (type === «обычный», без сортировки) :
arr.filter(item => {
if (item.type === "normal") {
return item
}
//sort array by referenceId and keeping last item
})
Комментарии:
1. Добро пожаловать в SO! Я немного смущен вашей логикой в
filter
обратном вызове. Какое отношениеitem.type === "normal"
имеет остальная часть вашей спецификации?2. только тип сортировки === «чат», если тип === «обычный», сортировки нет
Ответ №1:
Вы могли бы сделать сопоставление referenceId -> lastIndex
, а затем посмотреть индекс в своем filter
, чтобы сохранить только те индексы, которые соответствуют последнему для этого referenceId
. Выполняется проверка, чтобы убедиться, что мы отфильтровываем только type: "chat"
элементы. Временная сложность линейна.
const arr = [
{ id: 1, referenceId: 1, type: "normal", name: "a" },
{ id: 2, referenceId: 1, type: "normal", name: "b" },
{ id: 3, referenceId: 3, type: "chat", name: "c" },
{ id: 4, referenceId: 4, type: "normal", name: "d" },
{ id: 5, referenceId: 5, type: "chat", name: "e" },
{ id: 6, referenceId: 3, type: "chat", name: "f" }
];
const lastIdxes = arr.reduce((a, e, i) => {
a[e.referenceId] = i;
return a;
}, {});
const result = arr.filter((e, i) =>
e.type !== "chat" || i === lastIdxes[e.referenceId]
);
console.log(result);
Ответ №2:
Вы можете использовать сокращение следующим образом,
let arr = [
{ id: 1, referenceId: 1, type: "normal", name: "a" },
{ id: 2, referenceId: 2, type: "normal", name: "b" },
{ id: 3, referenceId: 3, type: "chat", name: "c" },
{ id: 4, referenceId: 4, type: "normal", name: "d" },
{ id: 5, referenceId: 5, type: "chat", name: "e" },
{ id: 6, referenceId: 3, type: "chat", name: "f" }
];
res = arr.reduce((prev, curr) => {
index = prev.findIndex(item => item.referenceId === curr.referenceId);
if(index > -1) {
prev.splice(index, 1);
}
prev.push(curr);
return prev;
}, []);
console.log(res);
Ответ №3:
сортировка по идентификатору, как указано в названии этого вопроса, а затем отслеживание того, когда будут удалены дубликаты
// sort by id and drop referenceId duplicates
const arr = [
{ id: 1, referenceId: 1, type: "normal", name: "a" },
{ id: 2, referenceId: 2, type: "normal", name: "b" },
{ id: 3, referenceId: 3, type: "chat", name: "c" },
{ id: 4, referenceId: 4, type: "normal", name: "d" },
{ id: 5, referenceId: 5, type: "chat", name: "e" },
{ id: 6, referenceId: 3, type: "chat", name: "f" }
];
arr.sort((a, b) => a.id > b.id ? 1 : -1);
const toDrop = [];
const mapper = {};
arr.forEach((curr, i) => {
if (mapper[curr.referenceId] !== undefined) {
toDrop.unshift(mapper[curr.referenceId]);
}
mapper[curr.referenceId] = i;
});
toDrop.forEach(i => {
arr.splice(i, 1);
});
console.log(arr);