2016-05-06 21 views
2

が、それはfrozensetによってセットのセットを持つことが可能です: セット(セットの...)Pythonで

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

は今のECMAScript 6が Setオブジェクトをもたらすことを、どのような方法ではありJavaScriptは、他のセットを一意に含むセットを持つ、つまり、同じアイテムを持つセット以外のすべてのセットを破棄するには?これが機能しないため

私が求めている:私は2つの{1}が別個見える理由です、Setは、おそらくそれが含まれて他のセットのポインタをハッシュすることを理解

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

。私が尋ねるのは、上記のPythonの動作を実現するためのJavaScriptの方法があるかどうかです。

+0

動作は正しいです。 's'と' t'は異なるオブジェクトなので、それらは区別されるべきです。 – trincot

+3

*「私が求めているのは、上に示したPythonの動作を実現するためのJavaScriptの方法があるかどうかです。」*いいえJavaScriptには、オブジェクトの平等を定義する方法はありません。 –

+0

@FelixKlingそうだとしたら、あなたの答えを記入してください、私はそれを受け入れます。 –

答えて

0

これは、オブジェクトであるJavaScript値が同じオブジェクトである場合にのみ等しいとみなされるためです。たとえば、{} === {}は、falseと評価されます。

@torazaburoによって指摘されているように、.add()コールをトラップし、既存のメンバーと同じアイテムをスキップするプロキシを作成できます。 lodashライブラリの_.isEqual()関数を使用して2つのセットを比較することができます。

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 demoを参照してください。

+0

私はJavaScriptに精通していませんが、O(n)で 'apply'を実行するのではないのですか?つまり、これは基本的にすでに含まれているすべてのセットを繰り返し処理し、それぞれを別のO(n)の 'Array.isEqual'と比較しますか?セットではなく配列を使う方法とどう違うのですか? –

+0

@EcirHanaそうです、それは配列を使うことと変わりありません。 –