简体   繁体   English

根据时间戳条件过滤数组中的唯一对象

[英]Filter unique objects in array based on timestamp condition

I have the following array:我有以下数组:

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

I need to filter the array based on the same ID, but also check the "lastUpdate" timestamp and keep only the newer entries.我需要根据相同的 ID 过滤数组,但还要检查“lastUpdate”时间戳并仅保留较新的条目。 The result should be:结果应该是:

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

I have tried the following:我尝试了以下方法:

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

However, this filters everything for me and the resulting array is empty.但是,这为我过滤了所有内容,结果数组为空。 I think something is wrong with the last part of above && t.lastUpdate > e.lastUpdate .我认为上面&& t.lastUpdate > e.lastUpdate的最后一部分有&& t.lastUpdate > e.lastUpdate

Many thanks for any tips!非常感谢您的任何提示!

Hi there if you are looking for a performant solution you can use an object :) 嗨,如果您正在寻找一种高性能的解决方案,则可以使用一个对象:)

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

You can achieve it by looking for items that don't have an item2 where the update was later 您可以通过查找没有item2的项目(稍后进行更新)来实现

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

What that code does is : 该代码的作用是:

For each item in the array it look if in the array there is an item with the same id where the lastUpdate is superior to its own. 对于数组中的每个项目,看一下数组中是否有一个具有相同ID的项目,其中lastUpdate优于其自身。 If there is one it return true (Array.some returns a boolean). 如果存在,则返回true(Array.some返回一个布尔值)。 We negate that value and use it to filter. 我们取反该值并使用它进行过滤。

You could do it step by step by converting to a set, sorting then getting the first item for each id: 您可以通过转换为集合,排序然后获取每个ID的第一项来逐步实现:

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

Silvio's approach packed into reusable code, reduces the OP's problem to eg something like that ... Silvio的方法包含在可重用的代码中,将OP的问题减少到例如类似的问题...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM