集合应该包含唯一对象,但它不适用于javascript中的对象.
var set = new Set()
<- undefined
set.add({name:'a', value: 'b'})
<- Set {Object {name: "a", value: "b"}}
set.add({name:'a', value: 'b'})
<- Set {Object {name: "a", value: "b"}, Object {name: "a", value: "b"}}
Run Code Online (Sandbox Code Playgroud)
它适用于基元
var b = new Set()
<- undefined
b.add(1)
<- Set {1}
b.add(2)
<- Set {1, 2}
b.add(1)
<- Set {1, 2}
Run Code Online (Sandbox Code Playgroud)
那么如何让它与对象一起工作呢?我得到的事实是,它们是具有相同值的不同对象,但我正在寻找像一个深刻的独特集合.
编辑:
这就是我实际在做的事情
var m = await(M.find({c: cID}).populate('p')) //database call
var p = new Set();
m.forEach(function(sm){
p.add(sm.p)
})
Run Code Online (Sandbox Code Playgroud)
这是为了获得一个独特的sm.p列表
小智 11
根据 Joe Yichong 的帖子,这里提出了扩展 TypeScript Set 的建议。
export class DeepSet extends Set {
add (o: any) {
for (let i of this)
if (this.deepCompare(o, i))
return this;
super.add.call(this, o);
return this;
};
private deepCompare(o: any, i: any) {
return JSON.stringify(o) === JSON.stringify(i)
}
}
Run Code Online (Sandbox Code Playgroud)
Cau*_*wer 10
另一种选择是您可以使用 JSON.stringify() 来保持对象的唯一性,这样它就可以与字符串而不是对象引用进行比较。
set.add(JSON.stringify({name:'a', value: 'b'}))
Run Code Online (Sandbox Code Playgroud)
然后在格式化所有内容后,您可以将这些行解析回数组,例如
const formattedSet = [...set].map(item) => {
if (typeof item === 'string') return JSON.parse(item);
else if (typeof item === 'object') return item;
});
Run Code Online (Sandbox Code Playgroud)
好吧,如果您正在寻找深层的唯一集合,则可以通过扩展原始的“集合”来自己制作深层集合,如下所示:
function DeepSet() {
//
}
DeepSet.prototype = Object.create(Set.prototype);
DeepSet.prototype.constructor = DeepSet;
DeepSet.prototype.add = function(o) {
for (let i of this)
if (deepCompare(o, i))
throw "Already existed";
Set.prototype.add.call(this, o);
};
Run Code Online (Sandbox Code Playgroud)
小智 -6
这是天真的,我确信有更好的方法来获取唯一数据(例如使数据库查询返回唯一数据,但这取决于数据库),但是您可以检查该对象是否已经在之前的集合中插入它。
var m = await(M.find({c: cID}).populate('p')) //database call
var p = new Set();
m.forEach(function(sm){
if(!p.has(sm.p)) p.add(sm.p)
})Run Code Online (Sandbox Code Playgroud)