2017-07-06 3 views
2

複数の異なるドキュメントを見ると、Map(ECMAScript6)キーがブール値、文字列、または整数の場合のみ表示されます。新しいカスタムオブジェクト(新しいCustomObject(x、y)コンストラクタ呼び出しで呼び出される)をキーとして追加する方法がありますか?Javascript Mapにオブジェクトキーがあるかどうかを確認する方法

オブジェクトをキーとして追加できますが、マップにそのオブジェクトがあるかどうかを確認できません。

var myMap = new Map(); 
myMap.set(new Tuple(1,1), "foo"); 
myMap.set('bar', "foo"); 


myMap.has(?); 
myMap.has('bar'); // returns true 

方法はありますか?

var myMap = new Map(); 
    myMap.set(new Tuple(1,1), "foo"); 

for(some conditions) { 
var localData = new Tuple(1,1); //Use directly if exists in myMap? 
map.has(localData) // returns false as this is a different Tuple object. But I need it to return true 
} 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has

+0

はい、あなたは任意のオブジェクトを使用することができます鍵として同じキーと値を持つオブジェクトだけでなく、毎回同じオブジェクトでなければなりません。ネストされた 'Map'は' Tuple'ルックアップを実装するための一つのオプションです。 – Ryan

+0

残念ながら、同じオブジェクトであるかどうかは確認できません。同じように設定されたいくつかの共通プロパティを持つオブジェクトでなければなりません。これを行う方法はありますか? –

答えて

3

あなただけのオブジェクトへの参照を保存する必要があります。

var myMap = new Map(); 
var myKey = new Tuple(1,1); 
myMap.set(myKey, "foo"); 
myMap.set('bar', "foo"); 

myMap.has(myKey);   // returns true; myKey === myKey 
myMap.has(new Tuple(1,1)); // returns false; new Tuple(1,1) !== myKey 
myMap.has('bar');   // returns true; 'bar' === 'bar' 

編集:ここでは、オブジェクトを比較することである、あなたが望むものを達成するためにオブジェクトを使用する方法であります

function Tuple (x, y) { 
    this.x = x; 
    this.y = y; 
} 
Tuple.prototype.toString = function() { 
    return 'Tuple [' + this.x + ',' + this.y + ']'; 
}; 

var myObject = {}; 
myObject[new Tuple(1, 1)] = 'foo'; 
myObject[new Tuple(1, 2)] = 'bar'; 
console.log(myObject[new Tuple(1, 1)]); // 'foo' 
console.log(myObject[new Tuple(1, 2)]); // 'bar' 

これらの操作はruです。 nを一定時間で平均すると、Mapを介して同様のオブジェクトキーを線形時間で検索するよりもはるかに高速です。

+0

ありがとうございます。残念ながら、私はオブジェクトに同じmyKey参照を使用することはできません。私は、同じプロパティのセットを持つオブジェクトをチェックしています。これを回避する方法はありますか? –

+0

@LoserCoderはい、同じ値を持つインスタンスに対して同じ文字列を生成するクラスのtoString()メソッドを作成し、それらの文字列をオブジェクトのキーとして使用します(Mapを使用する必要はありません) 。これは、単にJSでマップとオブジェクトの比較がどのように機能するかです。オブジェクトは参照によって比較されます。 – sbking

+0

@LoserCoder私が意味するものの例を追加しました。この方法は、toStringメソッドが比較のために値オブジェクトを正確に直列化できることを保証するためにあなたに任せます。同じコンストラクタと引数を使って2つのオブジェクトを作成しても、それらが必ずしも同等であるとは限りません。 – sbking

1

オブジェクトをマップに設定するときに、マップにオブジェクトがあるかどうかをチェックするときに、同じメモリ参照を渡す必要があります。あなたが本当にこれをしなければならない場合は、次の操作を行うことができ

const map = new Map(); 

map.set(new Tuple(1,1)); 
map.has(new Tuple(1,1)) // False. You are checking a new object, not the same as the one you set. 

const myObject = new Tuple(1,1); 
map.set(myObject); 
map.has(myObject) // True. You are checking the same object. 

EDIT

function checkSameObjKey(map, key) { 
    const keys = map.keys(); 
    let anotherKey; 

    while(anotherKey = keys.next().value) { 
     // YOUR COMPARISON HERE 
     if (key.id == anotherKey.id) return true; 
    } 

    return false; 
} 

const map = new Map(); 
map.set({id: 1}, 1); 

checkSameObjKey(map, {id: 1}); // True 
checkSameObjKey(map, {id: 2}); // False 
+0

真ですが、既知の回避策があるかどうかを探しています。または、このシナリオでSet/Mapを使用しないでください。もしそうなら、オブジェクト参照を直接使用しなければならないかもしれませんが、それは同じ問題を引き起こします。 –

+0

可能な回避策で私の答えを編集しました。 @LoserCoder – tiagodws

+0

このアプローチでは、JavaScriptエンジンの組み込みオブジェクトのキー解決アルゴリズム(ハッシュテーブル)を使用するよりも大幅に遅くなるリニアルックアップを使用します。これは平均して一定の時間です。 – sbking

関連する問題