JS - 在数组中使用 Set() 和对象

问题描述 投票:0回答:5

如何在对象中使用 Set() ?我阅读了文档,它适用于数组中的值,但不适用于对象。为什么?我想避免具有完全相同值的重复项目。

let nameList_one = [{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3  }]
let nameList_two = [{ name: 'harry', id: 1  }, { name: 'ron', id: 4  }, { name: 'jackson', id: 5  }]

let fullNameList = [...nameList_one , ...nameList_two ]

let filteredList = [...new Set(fullNameList)] // the output is the merge of two array, duplicating "harry".

输出:

[{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3 }, { name: 'harry', id: 1 }, { name: 'ron', id: 4 }, { name: 'jackson', id: 5 }]

预期输出:

[{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3 }, { name: 'ron', id: 4 }, { name: 'jackson', id: 5 }]

谢谢!!

javascript arrays ecmascript-6
5个回答
28
投票

这不适用于对象,因为它们不是相同的对象:

{ name: 'harry', id: 1 } !== { name: 'harry', id: 1 }

一种可能有效的方法是:

let filteredList = [...new Set(fullNameList.map(JSON.stringify))].map(JSON.parse);

不推荐这样做,因为它在不必要的地方使用了序列化。序列化将销毁无法序列化的对象实例,将忽略不可枚举的属性,并且不会处理循环引用。具有不同属性顺序的对象不会作为重复项被删除。应首先对它们的属性进行排序。如果存在嵌套对象,则应对键进行递归排序。这使得这种方法不切实际。

如果对象由一个或多个字段标识,则可以使用序列化字段作为映射键的

Map

let filteredList = [
  ...new Map(fullNameList.map(obj => [`${obj.id}:${obj.name}`, obj]))
  .values()
];

8
投票

这样做的一个好方法是子类化

Set

class UniqueNameSet extends Set {
    constructor(values) {
        super(values);

        const names = [];
        for (let value of this) {
            if (names.includes(value.name)) {
                this.delete(value);
            } else {
                names.push(value.name);
            }
        }
    }
}

这为您提供了

Set
的所有其他方法/属性,但添加了您正在寻找的额外功能。


3
投票

每个对象都是一个指向内存地址的指针,因此即使两个对象具有相同的属性,它们也不会相等。 一种方法是使用 JSON.stringify 并复制字符串化对象。


0
投票

要获取对象数组的唯一字段,如果您对该字段有了解,可以尝试这个。

const data = [{name: 'Bob'}, {name: 'John'}, {name:'Bob'}];

const res =  data.reduce((acc, curr, idx, arr)=> {
  if(acc[1].indexOf(curr.name)==-1) {
      acc[1].push(curr.name);
      acc[0].push(curr)
  }
  return acc
}, [[],[]])[0]

console.log(res)

 //[{ name: "Bob" }, Object { name: "John" }]


-2
投票

为了清晰

const array = [
  {
    name: "Joe",
    age: 17,
  },
  {
    name: "Joe",
    age: 17,
  },
  {
    name: "Carl",
    age: 35,
  }
];

let myArray = [];

for(let a = 0; a < array.length; a++){

   let string = JSON.stringify(array[a]);

   myArray.push(string)

};

const set = new Set(myArray);

let newArray = [];

set.forEach((element) => {

  const parsedData = JSON.parse(element);

  newArray.push(parsedData);

});
© www.soinside.com 2019 - 2024. All rights reserved.