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

时间:2019-01-25 13:58:33

标签: javascript arrays node.js ecmascript-6

我有以下数组:

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

我需要基于相同的ID过滤数组,还需要检查“ 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 :(得分:4)

您好,如果您正在寻找一种高性能的解决方案,则可以使用一个对象:)

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

答案 1 :(得分:2)

您可以通过查找没有item2的项目来实现此目的

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

该代码的作用是:

对于数组中的每个项目,看一下数组中是否有一个具有相同ID的项目,其中lastUpdate优于其自身。 如果存在,则返回true(Array.some返回一个布尔值)。 我们会否定该值并将其用于过滤。

答案 2 :(得分:0)

您可以通过转换为集合,进行排序然后为每个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);

答案 3 :(得分:0)

Silvio's approach打包到可重用代码中,将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; }