一组(共组..)

Set of sets (of sets...)

本文关键字:共组 一组      更新时间:2023-09-26

在Python中,可以通过frozenset:获得一组集合

s, t = frozenset([1]), frozenset([1])
u = {s, t} # u == {frozenset([1])}

既然ECMAScript 6带来了Set对象,那么在JavaScript中有没有任何方法可以让一个集合唯一地包含其他集合,即丢弃除了一个具有相同项的集合之外的所有集合?

我问是因为这不起作用:

var s = new Set([1]), t = new Set([1]);
var u = new Set([s, t]); // u == Set{Set{1}, Set{1}}

我知道Set可能会对它包含的其他集合的指针进行散列,这就是为什么两个{1}看起来不同的原因。我想问的是,在JavaScript中是否有实现上述Python行为的方法。

这是因为在JavaScript中,作为对象的值只有在它们是同一对象时才被视为相等。例如,{} === {}的求值结果为false

正如@torazaburo所指出的,您可以为该集合创建一个代理,该代理将捕获.add()调用并跳过与任何现有成员相等的项。您可以使用lodash库中的_.isEqual()函数来比较两个集合。

const firstSet = new Set([1])
     ,secondSet = new Set([1])
const newSet = new Set()
newSet.add = new Proxy(newSet.add, {
  apply: (target, thisArg, [value])=> {
    // Array.from() is required to use Array.prototype.some()
    if (!Array.from(newSet).some(element=> _.isEqual(element, value))) {
      target.call(newSet, value)
    }
    return target
  }
})
newSet.add(firstSet)
newSet.add(secondSet)
console.log(newSet.has(firstSet))  // logs true
console.log(newSet.has(secondSet)) // logs false, because secondSet 
                                   // has not been added, since it's a duplicate
console.log(newSet.size)           // logs 1

请参阅JS Bin演示。