2016-08-15 15 views
4

Set.prototype.has()述語と

var myset = new Set(); 
 
    
 
myset.add({ key: 123, value: 100 }); 
 
var has = myset.has({ key: 123, value: 100 });  
 
console.log(has); // false 
 
     
 
var obj = { 
 
    key: 456, 
 
    value: 200 
 
}; 
 

 
myset.add(obj); 
 
has = myset.has(obj); 
 
console.log(has); // true 
 
    
 
has = myset.has(x => x.key === 123);  
 
console.log(has); // false

この場合の問題点:私はちょうどmysetから{ key: 123, value: 100 }を追加し、なぜそれが{ key: 123, value: 100 }が含まれていませんか?

{ key: 123, value: 100 }の代わりにobjを使用すると、trueが返されます。

Set.prototype.has()は言う:

ザ有する()メソッドは、指定された値を持つ要素が設定オブジェクトに存在するか否かを示すブール値を返します。

しかし、それについては言及していません:specified valueは何ですか?

明らかに、この場合{ key: 123, value: 100 }{ key: 123, value: 100 }は、と同様です。私はfalseを取得しています。ではspecifiedは何ですか?

もう1つ質問:has()の方法でpredicateをサポートしていないのはなぜですか?

私の例では、それは叙述でインラインになることができますが

for (let obj of myset) { 
    if (obj.key === 123) return true; 
} 

has = myset.has(x => x.key === 123) 

だから、それは将来のために改善すべきそれは私がfor...of...を使用する場合、検索するのは難しいのか?

+3

https://esdiscuss.org/topic/maps-with-object-keys申し訳ありません、うん。実際のユースケースではJSの地図が壊れていて、その地図を修正すると言った人はいないだろう。述語や構造的平等はサポートされていません。なぜなら、言語を使って作業することは何千時間も必要な恩知らずの仕事であり、ほとんどの人はそれを入れる意思がないからです。 –

+0

@BenjaminGruenbaum ya。ありがとう!私はECMAScript 2018を待っています:) –

答えて

1

{ key: 123, value: 100 } === { key: 123, value: 100 }falseです。JavaScriptは浅い比較を実行するためです。各オブジェクトリテラルは新しいオブジェクトを作成しますが、同じ値を保持していても、まるで同じように見える別のオブジェクトです。この例では

var a = {}; 
var b = a; 
a === b; // true 

あなたは今、あなたが同じオブジェクトを比較しているので、trueを取得します。 aの変更がbに反映されているため、abが同じオブジェクトであることがわかります。ここ

a.x = 1; 
b.x === 1; // true 

myset.has(x => x.key === 123)セットが作成したばかりのこの新しいラムダを持っている場合、あなたは求めています。 hasがあなたのラムダを使用してセットの要素をチェックするといいでしょうが、残念なことにこのメソッドはこのチェックを実行します。

1

Set.prototype.hasは、それがvalue equalityを使用してテストしているため、オブジェクトを見つけることを意味しません:

{ key: 123 } !== { key: 123 } // true 

あなたが述語に基づいてアイテムを見つけることができるようにしたい場合は、手動でその機能を追加する必要があります。 Setは、反復なしで高速検索が必要な場合にのみ効率的であるため、関数はおそらく存在していない可能性があります。値を反復処理する場合は、代わりに配列を使用します。ここで

はあなただけArray.prototype.findとしてそれを実装できる方法は次のとおりです。

Set.prototype.find = function() { 
    return Array.prototype.find.apply([...this], arguments); 
};