[英]How to get deep-equality of keys in ES6 Map? Alternative to using complex object as ES6 Map key?
下面是一些示例Javascript(ES6)代碼,它沒有做出人們可能直觀想象的代碼。
const exampleMap = new Map([[{a: 1}, 2]]);
console.log(exampleMap.get({a: 1}));
事實證明,這打印undefined
。 為什么? StackOverflow答案涵蓋了推理。 根據Map的MDN條目 , Map
使用===
表示密鑰相等。 並且,根據===
的MDN條目 ,通過引用相等性來比較Object
。
這一切都很好,很好。 它完全符合文檔的說法。 不幸的是,上面的代碼嘗試做的事情非常有用,即使它不是規范的實際行為。
我如何使用Map
,或者我應該使用什么而不是Map
來獲取鍵值查找,其中鍵是通過對象深度等同語義進行比較的?
您可以創建自己的函數,在其中傳遞要獲取其值的地圖( m
)以及要在地圖中搜索的key
。 然后,您可以對密鑰進行字符串化,以便您可以搜索地圖中的密鑰並將其與此字符串化密鑰進行比較
const exampleMap = new Map([[{a: 1}, 2]]); const getMapVal = (m, key) => { const strKey = JSON.stringify(key); return m.get(Array.from(m.keys()).find((k) => JSON.stringify(k) === strKey)); } console.log(getMapVal(exampleMap, {a: 1})); // 2 (gives undefined if key doesn't exists)
這是進行深度平等檢查的東西。 它依賴於JSON.stringify
因此它可能是非常大的對象鍵的性能問題。 這也以與.get
相同的方式更新Map
原型。
Object.defineProperty(Map.prototype, 'deepCheck', { value: function(lookupKey) { let lookupValue; const lookupKeyStr = JSON.stringify(lookupKey); if (this == null) { throw new TypeError('this is null or not defined'); } const iterator = this.entries(); let result = null; while (true) { result = iterator.next(); if (result.done) { break; } if (JSON.stringify(result.value[0]) === lookupKeyStr) { lookupValue = result.value[1]; } } return lookupValue; } }); const exampleMap = new Map([[{a: 1}, 2]]); console.log(exampleMap.deepCheck({a: 1}));
您需要以某種方式比較或獲取對用作Map鍵的確切對象的引用。 一個辦法是遍歷地圖的entries
,並檢查是否有指其密鑰具有a
值1:
const exampleMap = new Map([[{a: 1}, 2]]); const foundEntry = [...exampleMap.entries()] .find(([key, val]) => key.a === 1); console.log( foundEntry ? foundEntry[1] : 'Not found!' );
另一種方法:
const exampleMap = new Map([[{a: 1}, 2]]); const foundKey = [...exampleMap.keys()] .find(key => key.a === 1); console.log( foundKey ? exampleMap.get(foundKey) : 'Not found!' );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.