Фильтрация уникальных объектов в массиве по условию временной метки - PullRequest
0 голосов
/ 25 января 2019

У меня есть следующий массив:

let arr = [
    {"id": 123, "lastUpdate": 1543229793},
    {"id": 456, "lastUpdate": 1545269320},
    {"id": 123, "lastUpdate": 1552184795}
]

Мне нужно отфильтровать массив на основе того же идентификатора, но также проверить отметку времени «lastUpdate» и сохранить только новые записи. Результат должен быть:

[
    {"id": 456, "lastUpdate": 1545269320},
    {"id": 123, "lastUpdate": 1552184795}
]

Я пробовал следующее:

arr = arr.filter((e, index, self) =>
    index === self.findIndex((t) => (
        t.id === intent.id && t.lastUpdate > e.lastUpdate
    ))
)

Однако, это фильтрует все для меня, и полученный массив пуст. Я думаю, что что-то не так с последней частью выше && t.lastUpdate > e.lastUpdate.

Большое спасибо за любые советы!

Ответы [ 4 ]

0 голосов
/ 25 января 2019

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

function collectUniqueItemByIdWithMostRecentUpdate (collector, item, idx, arr) {
    const store = collector.store;
    const storedItem = store[item.id];

    if (!storedItem || (storedItem.lastUpdate < item.lastUpdate)) {
        store[item.id] = item;
    }
    if (idx >= (arr.length - 1)) {
        collector.list = Object.values(store);
    }
    return collector;
}

let arr = [
    {"id": 123, "lastUpdate": 1543229793},
    {"id": 456, "lastUpdate": 1555269320},
    {"id": 123, "lastUpdate": 1552184795},
    {"id": 456, "lastUpdate": 1545269320},
    {"id": 123, "lastUpdate": 1553229793}
];

console.log(arr.reduce(collectUniqueItemByIdWithMostRecentUpdate, {

    store: {},
    list: []

}).list);
.as-console-wrapper { max-height: 100%!important; top: 0; }
0 голосов
/ 25 января 2019

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

let arr = [
    {"id": 123, "lastUpdate": 1543229793},
    {"id": 456, "lastUpdate": 1545269320},
    {"id": 123, "lastUpdate": 1552184795}
]

// Get the ids by making a set of ids and then converting to array
let ids = [ ...new Set(arr.map((e) => e.id)) ];

// Sort the original by lastUpdate descending
arr.sort((a, b) => b.lastUpdate - a.lastUpdate);

// Get array of first item from arr by id
let res = ids.map(id => arr.find((e) => e.id == id));

console.log(res);
0 голосов
/ 25 января 2019

Привет, если вы ищете эффективное решение, вы можете использовать объект:)

let arr = [{"id": 123,"lastUpdate": 1543229793},
{"id": 456,"lastUpdate": 1545269320},
{"id": 123, "lastUpdate": 1552184795}];

let newArr = {}
arr.forEach(el => {
  if(!newArr[el.id] || newArr[el.id].lastUpdate < el.lastUpdate){
      newArr[el.id] = el
  }
})

console.log(Object.values(newArr));
0 голосов
/ 25 января 2019

Вы можете достичь этого, ища предметы, у которых нет item2, где обновление было позже

   arr.filter(item => 
                 { return !arr.some(item2 => 
                  item.id === item2.id && item.lastUpdate < item2.lastUpdate)
            });

Что делает этот код:

Для каждого элемента в массиве это выглядит, если в массиве есть элемент с таким же идентификатором, где lastUpdate превосходит его собственный. Если он есть, он возвращает true (Array.some возвращает логическое значение). Мы отрицаем это значение и используем его для фильтрации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...