使用Javascript中的Set去除重复项

6

我正在处理一件本应该非常简单的事情。我有一个对象数组,需要根据 id 属性从这个数组中移除重复项。因此,我想创建一个包含我的 id 的 Set,如下所示:

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
console.log('indexes list', indexes)

但是索引总是为空。我做错了什么?谢谢。
编辑:我选择@Hyyan Abo Fakher的答案是正确的,因为他是正确的,但是@bambam评论中的建议是整个问题的一个很好的解决方案。感谢大家。

1
你使用的是哪个浏览器和版本?尝试 console.log(Array.from(indexes))。不管怎样,只使用reduce会更容易:const unique = arr.reduce((a,b) => a.find(({id}) => id === b.id) ? a : a.concat(b) , []); - baao
3
无法复现。你确定 this.myArray 不是空的吗? - Sergio Tulentsev
很好的解决方案:使用ECMA6 Set。 - Dennis Guse
你的代码可行。为什么要使用this.myArray?请分享完整片段。 - Waqas Noor
我怀疑 OP 已经意识到了他们的错误并填充了this.myArray,然后发现代码可以工作。 - Reinstate Monica Cellio
1
@Archer:是啊,讨厌那些失踪的 OP :) - Sergio Tulentsev
4个回答

9
你可以使用 Setfilter 方法来创建一个由唯一 id 对象组成的新数组。

const data = [{id: 10, other: "bla"},{id: 15, other: "meh"},{id: 10, other: "bla"}]

let result = data.filter(function({id}) {
  return !this.has(id) && this.add(id);
}, new Set)

console.log(result)


真的是一个很棒的方法! - Leonid Pyrlia
@Leonid Pyrlia 谢谢。 - Nenad Vracar
我喜欢这个,但对我没用... 正在努力理解原因。 - esseara

2

但是索引始终为空。我做错了什么?

您的代码完全可用,问题似乎来自浏览器控制台本身,您期望将set打印到控制台将会像数组一样打印出set的项,但实际上,浏览器只会打印对象实例。

在StackOverflow上运行您的代码将打印indexes list {},但实际上,浏览器控制台打印了其他内容。

enter image description here

为了确保列表不为空,使用size属性。

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
console.log('indexes list', indexes.size)

要循环遍历这个集合,你需要使用 for ... of

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
for (let item of indexes) console.log(item);


1

我们可以通过循环使用数组来解决这个问题,如下所示:

var b = [];
a.forEach(function(index){
   if(b[index.id]==undefined){
       b[index.id] = index.other;
   }
});
console.log(b);

这里 a 是原始的源数组。


2
你为什么要两次赋值给 b[index.id] - Barmar
最初 b[index.id] 将是未定义的,因此在添加值之前应该初始化它。 - Bannarisamy Shanmugam
@BannarisamyShanmugam:但是你没有给它添加任何值。 - Sergio Tulentsev
你不需要创建属性或初始化任何内容。你可以直接删除 b[index.id] = "";,因为它根本不是必需的。 - Reinstate Monica Cellio
1
@Archer,你说得对。我不需要启动它。谢谢。 - Bannarisamy Shanmugam

1

您可以检查集合是否具有该ID,如果没有,则将元素推送到新数组中。最终的数组将具有唯一的元素。

var source = [
  {id: 10, other: "bla"},
  {id: 15, other: "meh"},
  {id: 10, other: "bla"}
];

var set = new Set();
var result = [];

source.forEach(item => {
  if (!set.has(item.id)) {
    set.add(item.id);
    result.push(item);
  }
})

console.log(result);


为什么要推到一个新数组,当你可以直接使用集合呢? - Barmar
@Barmar -- 这个集合只包含对象的ID。 - 31piy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接