使用 Set 从数组中删除重复项,保持最高 id

Posted

技术标签:

【中文标题】使用 Set 从数组中删除重复项,保持最高 id【英文标题】:Remove duplicates from array using Set, keeping highest id 【发布时间】:2019-11-22 16:49:57 【问题描述】:

我有这个数组:

array = [id: 1, name: 'apple', id: 2, name: 'banana', id: 3, name: 
'apple']

我需要删除具有重复属性“名称”的对象,并且我需要为剩余对象保留最高 id,如下所示:

newarray = [ id: 2, name: 'banana', id: 3, name: apple]

我试过这种方式:

array = [id: 1, name: 'apple', id: 2, name: 'banana', id: 3, name: 
apple]

newarray = Array.from(new Set(array.map(x => x.id)))
                 .map(id => 
                   return 
                     id: id,
                     name: array.find( s => s.id === id).name
)

我得到的结果

newarray = [ id: 2, name: 'banana', id: 1, name: apple]

我删除了重复的对象,但是我没有得到每个剩余对象的最高 id。

谢谢你给我一个想法。

【问题讨论】:

ids 在原始数组中是否像示例中那样按顺序排列? 这似乎是完成工作的荒谬方式。为什么不直接删除重复项然后进行反向排序? 【参考方案1】:

我会改用reduce - 缩减为按名称索引的对象,其值是关联的id / name 对象。如果对象已经以给定名称存在,则仅当新对象的 ID 更高时才重新分配:

const array = [id: 1, name: 'apple', id: 2, name: 'banana', id: 3, name: 
'apple'];

const newArray = Object.values(
  array.reduce((a, item) => 
    const  name  = item;
    if (!a[name] || a[name].id < item.id) 
      a[name] = item;
    
    return a;
  , )
);
console.log(newArray);

【讨论】:

你也可以这样做来简化它array.reduce((a, name, id =&gt; @GetOffMyLawn 我考虑过,但我不完全确定 OP 是否想要保留对原始对象的引用,或者只需要每个对象中的数据 实际上你需要这个 (a, name, id, idx, orig)a[name] = orig[idx]; 无论哪种方式都有效【参考方案2】:

我设法结合使用 map、filter 和 reduce :)

代码cmets中的解释。

请看下面的演示

var array = [
  id: 1,
  name: 'apple'
, 
  id: 2,
  name: 'banana'
, 
  id: 5,
  name: 'banana'
, 
  id: -9,
  name: 'pear'
, 
  id: 3,
  name: 'apple'
, 
  id: -3,
  name: 'pear'
];

/*
  1 - it creates a Set from mapping original array into a list of names
  2 - it then maps it back into the objects but this time 
     2.1 - it filters the original array to elements with only matching names
     2.2 - and then it reduces the id to the highest value
*/
var filteredArray = Array.from(new Set(array.map(x => x.name))).map(e => 
  return 
    id: array.filter(function(el)
      return el.name == e;
    ).reduce((curr, next) => curr.id > next.id ? curr.id : next.id, 0),
    name: e
  
);

console.log(filteredArray);

【讨论】:

【参考方案3】:

您也可以使用sortreduce 来达到预期的效果

Object.prototype.use = function(fn) 
  return fn(this)


var res = [
    id: 1,
    name: 'apple'
  , 
    id: 2,
    name: 'banana'
  , 
    id: 3,
    name: 'apple'
  ]
  .sort((a, b) => b.id - a.id)
  .reduce((o, d) => o[d.name] ? o : ( ...o, [d.name]: d ), )
  .use(r => Object.values(r))

console.log(res)

【讨论】:

以上是关于使用 Set 从数组中删除重复项,保持最高 id的主要内容,如果未能解决你的问题,请参考以下文章

使用 JavaScript 从数组中删除所有重复项 [重复]

如何从 Python 列表中删除重复项并保持顺序? [复制]

Java从数组中删除重复项?

从对象数组中的嵌套数组中删除重复项

使用新 Set 删除数组中的重复项会出错

Pyspark - 从数据框中删除重复项,保持最后一次出现