从那时起,获取没有重复项的数组的代码变得很优雅ES6:
[...new Set(array)];
就是这样!
但是,这仅在数组包含原始数据类型(字符串、布尔值、数字……)的元素时删除重复项。
一组对象文字怎么样?如何在不重复的情况下使其工作,使用与上面使用的语法接近的语法?
var array=["aaa","bbb","aaa","cc","aaa","bbb"];
var out=[...new Set(array)];
console.log(out)
//----Literal Object
array=[{n:"J",last:"B"},{n:"J",last:"B"}];
out=[...new Set(array)];
console.log(out)
上面的代码生成一个包含 2 个元素的集合,但在本例中我希望它只有一个。
我可以使用序列化/反序列化方法来实现这一点:
[...new Set(array.map(
//-- SERIALIZE:
(e) => `${e.n}:${e.last}`
))].map(
//-- DE-SERIALIZE:
(e) => ({ n: `${e.split(':')[0]}`, last: `${e.split(':')[1]}` })
)
不过,我正在寻找 ES6 内置的。
在 JavaScript 中,如果两个对象不是相同的引用,则它们是不同的,即使它们看起来相同:
var a = {};
var b = {};
console.log(a === b); // false
b = a;
console.log(a === b); // true
集合的工作方式类似:除非添加到其中的对象引用相同的事物,否则它们将是不同的。
定制套装
让它按照你想要的方式工作的一个想法是创建你自己的 Set 风格,即MySet,为其提供作为 Set 工作所需的所有方法和属性。
然后在其实现中,您将在其内部保留一个 Map,您可以在其中为存储在其中的所有内容提供一个密钥。然后,您可以确保您认为相同的对象在该映射中获得相同的键,因此仅存储一次。
一种低效但简单的方法是使用JSON.stringify(item)
作为关键。这有其局限性(例如,添加自引用对象将使JSON.stringify(item)
放弃),但对于其余的事情它完成了工作。
我们可以做MySet接受附加参数:调用以获取项目的键值的函数。鉴于上述想法,我们将给它默认值JSON.stringify
.
考虑这个实现,并添加了您的测试代码:
// Implementation of special Set:
class MySet {
constructor(values = [], keyFunc = JSON.stringify) {
// Use a map to store the values
this._map = new Map();
// Which function to use for generating an item's key
this._keyFunc = keyFunc;
// Add the initial values
for (var value of [...values]) this.add(value);
}
get size() {
return this._map.size;
}
add(item) {
// Key items by the given function
this._map.set(this._keyFunc(item), item);
}
has(item) {
return this._map.has(this._keyFunc(item));
}
*[Symbol.iterator] () {
for (var pair of this._map) {
yield pair[1]; // return the item
}
}
// etc...
}
// Test it:
array = [{n:"J",last:"B"}, {n:"J",last:"B"}];
out = [...new MySet(array)];
console.log(out);
正如您所看到的,虽然集合中添加了两个对象,但它只存储了一个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)