JS-过滤对象数组以查找一个属性的重复项,并根据另一个属性确定要保留的对象

时间:2018-10-29 09:22:29

标签: javascript arrays filter duplicates javascript-objects

尝试通过消除具有另一个对象中已经存在的特定属性的对象来过滤对象数组(重复)。决定要删除哪个对象应该基于另一个属性。

示例: 对于一组可能看起来像这样的对象,目标是过滤所有“用户”重复项,并保留具有最旧“日期”属性的对象。

const arr = [
    {user: 'Alex', date: '1540801929945'},
    {user: 'Bill', date: '1640801929946'},
    {user: 'Carl', date: '1740801929947'},
    {user: 'Alex', date: '1840801929948'},
]

预期结果:

filteredArr = [
    {user: 'Alex', date: '1540801929945'},
    {user: 'Bill', date: '1640801929946'},
    {user: 'Carl', date: '1740801929947'},
]

我管理了仅用于保留唯一对象的基本过滤器。

const filteredArr = arr.reduce((unique, o) => {
    if(!unique.some(obj => obj.user === o.user) {
      unique.push(o);
    }
    return unique;
},[]);

尽管我不知道,该怎么做,以便在重复的情况下保留“最旧的”对象,并删除最新的对象。 非常感谢你的帮助!非常感谢。

4 个答案:

答案 0 :(得分:1)

将数组简化为以user为键的对象。如果用户不在unique对象中,或者用户的日期比该日期“早”,则将其添加到该对象中。用Object.values()将对象转换为数组。

注意:由于您的日期是字符串,因此在比较时将它们转换为数字(我使用+ operator)。

const array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }];


const filteredArray = Object.values(array.reduce((unique, o) => {
  if(!unique[o.user] || +o.date > +unique[o.user].date) unique[o.user] = o;
  
  return unique;
}, {}));

console.log(filteredArray);

答案 1 :(得分:1)

使用Map和单循环方法的解决方案

var array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }],
    filtered = Array.from(array
        .reduce((m, o) => !m.has(o.user) || m.get(o.user).data > o.date
            ? m.set(o.user, o)
            : m, new Map)
       .values());
      
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }

对于排序的数据(以date进行排序),可以使用Set进行过滤。

var array = [{ user: 'Alex', date: '1540801929945' }, { user: 'Bill', date: '1640801929946' }, { user: 'Carl', date: '1740801929947' }, { user: 'Alex', date: '1840801929948' }],
    filtered = array
        .sort(({ date: a }, { date: b }) => a - b)
        .filter((s => ({ user }) => !s.has(user) && s.add(user))(new Set));
      
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

对于O(N)解决方案,将reduce放入由user索引的对象,该对象的值为date s-在每次迭代中,如果该{{1} }已经存在,请仅保留最低的user。然后,遍历对象的date以将其变回数组:

entries

答案 3 :(得分:0)

我相信您实际上需要知道非唯一元素(在您的情况下名称为“ Alex”的对象)的索引,然后比较它们的日期,以保存较旧的日期。

在这种情况下,Array.prototype.find不会带来任何好处。 但是,Array.prototype.find会有所帮助,因为它需要一个回调函数,该回调函数返回一个boolean(就像'some')一样,但是它返回与您的回调函数匹配的元素的索引;如果找不到这样的元素,则返回undefined。 / p>

尝试一下,不会受伤:)