#javascript #reduce
Вопрос:
У меня есть массив сообщений, и я хотел бы сократить его, чтобы он содержал только самые новые версии этих сообщений.
Я решил проблему с обычным старым JS с помощью: для каждого сообщения помещайте каждое сообщение в словарь с ключом id
, перезаписывая предыдущие версии, а затем преобразуйте dict в массив с помощью Array.from(mathes.values)
Но я хотел бы узнать больше о современных ES JS — и подозреваю, что есть умная карта/сокращение, чтобы решить мою проблему.
const messages = []
messages.push({id: 1, ver:1})
messages.push({id: 2, ver:1})
messages.push({id: 3, ver:1})
messages.push({id: 1, ver:2})
messages.push({id: 2, ver:2})
messages.push({id: 2, ver:3})
const newest = [] // some fancy map/reduce
console.log(newest)
// [{id: 1, ver:2},
// {id: 2, ver:3},
// {id: 3, ver:1}]
Может ли кто-нибудь помочь мне с картой/уменьшением, чтобы выполнить вышеуказанное?
Ответ №1:
Одним из вариантов было бы сопоставить объекты в массив записей, которые превращаются в объект с Object.fromEntries
, таким образом, сохраняя только последние идентификаторы:
const arr = [
{id: 1, ver:1},
{id: 2, ver:1},
{id: 3, ver:1},
{id: 1, ver:2},
{id: 2, ver:2},
{id: 2, ver:3},
];
const dedup = Object.values(
Object.fromEntries(
arr.map(item => [item.id, item])
)
);
console.log(dedup);
Комментарии:
1. Решение в порядке, пока версии в порядке. Если это не так, его нужно будет отсортировать.
2. Красиво преподнесено, спасибо. Версии в порядке, так что мне не нужно беспокоиться об этом 🙂
Ответ №2:
Простое сокращение, которое проверяет, является ли версия больше. После создания объекта просто извлекает из него значения.
const messages = []
messages.push({id: 1, ver:1})
messages.push({id: 2, ver:1})
messages.push({id: 3, ver:1})
messages.push({id: 1, ver:2})
messages.push({id: 2, ver:2})
messages.push({id: 2, ver:3})
const newest = Object.values(messages.reduce((acc, item) => {
if (!acc[item.id] || acc[item.id].ver < item.ver ) {
acc[item.id] = item;
}
return acc;
}, {}));
console.log(newest);