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

Joh*_*son 6 javascript arrays ecmascript-6

如何在对象中使用 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".
Run Code Online (Sandbox Code Playgroud)

输出:

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

预期输出:

[{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3 }, { name: 'ron', id: 4 } ,{名称:'杰克逊',ID:5}]

谢谢!!

Est*_*ask 14

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

{ name: 'harry', id: 1 } !== { name: 'harry', id: 1 }
Run Code Online (Sandbox Code Playgroud)

一种可行的方法是:

let filteredList = [...new Set(fullNameList.map(JSON.stringify))].map(JSON.parse);
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 将对象转换为字符串表示形式。不客气。 (2认同)

lon*_*day 5

这样做的一个好方法是将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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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