套套(套套...)

Eci*_*ana 6 javascript set ecmascript-6

在Python中,可以通过以下方式拥有一组集合frozenset

s, t = frozenset([1]), frozenset([1])
u = {s, t} # u == {frozenset([1])}
Run Code Online (Sandbox Code Playgroud)

既然 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}}
Run Code Online (Sandbox Code Playgroud)

我知道这Set可能会散列它所包含的其他集合的指针,这就是为什么两者{1}看起来不同的原因。我要问的是 JavaScript 中是否有一种方法可以实现上面所示的 Python 行为。

Mic*_*ski 2

这是因为在 JavaScript 中,作为对象的值只有在它们是同一个对象时才被认为是相等的。例如{} === {}评估为false.

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

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
Run Code Online (Sandbox Code Playgroud)

请参阅JS Bin 演示

  • 我不太精通 JavaScript,但是 `apply` 的运行时间不是 O(n) 吗?我的意思是,这基本上是迭代所有已包含的集合并将每个集合与另一个 O(n) 中的“Array.isEqual”进行比较吗?它与使用数组而不是集合有何不同? (2认同)