[英]Using Array objects as key for ES6 Map
我正在嘗試將我的代碼更新為 ES6,因為我使用的是 Node 4.0 並且到目前為止非常喜歡它的功能。 但是,我對新的 ES6 Map
數據結構有問題,因為它在使用Array
作為鍵時的行為與{}
不同。 我將其用作計數器地圖。
我運行此代碼,我想知道如何使用數組作為Map
鍵。
"use strict";
var a = new Map();
a.set(['x','y'], 1);
console.log(a.get(['x','y']));
var b = {};
b[['x','y']] = 1;
console.log(b[['x','y']]);
它打印出以下內容,第一行應該是1
而不是undefined
:
undefined
1
原始 JS 映射將鍵字符串化,我不想對新的 ES6 Map
進行相同類型的字符串化破解。
我該怎么做才能可靠地使用數組作為 ES6 Map
鍵?
了解 ES2015 Map 鍵(幾乎)與===
運算符進行比較。 兩個數組實例,即使它們包含相同的值,也不會相互比較為===
。
嘗試這個:
var a = new Map(), key = ['x', 'y'];
a.set(key, 1);
console.log(a.get(key));
由於 Map 類旨在用作基類,因此您可能可以使用覆蓋.get()
函數來實現子類。
(第一句中的“幾乎”是為了反映 Map 鍵相等性比較是通過Object.is()
,這在日常編碼中很少出現。它本質上是 JavaScript 中相等性測試的第三種變體。 )
我也有這個需求,所以我寫了一個 ISC 許可的庫: array-keyed-map 。 你可以在 npm 上找到它。 我認為來源很清楚,但無論如何,這是它的工作原理,供后代使用:
維護一個Map
對象樹。 每棵樹存儲:
在內部聲明的Symbol
鍵下:樹中該點的值(如果有)。 Symbol
保證唯一性,因此沒有用戶提供的值可以覆蓋此鍵。
在它的所有其他鍵上:所有其他到目前為止從這棵樹設置下一個樹。
例如,在akmap.set(['a', 'b'], true)
,內部樹結構將類似於——
'a':
[value]: undefined
'b':
[value]: true
之后執行akmap.set(['a'], 'okay')
只會更改'a'
路徑的值:
'a':
[value]: 'okay'
'b':
[value]: true
要獲取數組的值,請在從樹中讀取相應鍵的同時遍歷數組。 如果任意點的樹不存在,則返回undefined
。 最后,從你已經到達的樹中讀取內部聲明的[value]
符號。
要刪除數組的值,請執行相同操作,但刪除[value]
-symbol-key 下的所有值,並在遞歸步驟后刪除所有size
為 0 的子樹。
為什么是一棵樹? 因為當多個數組具有相同的前綴時非常有效,這在實際使用中非常典型,用於處理例如文件路徑。
您需要保存對用作鍵的Array
的非原始實例的引用。 請注意以下兩個示例的不同之處:
"use strict"; var a = new Map(); a.set(['x','y'], 1); console.log(a.get(['x','y'])); console.log(['x','y'] === ['x','y']); var b = new Map(); var array = ['x','y']; b.set(array, 1); console.log(b.get(array)); console.log(array === array);
如果有人在這里尋找更基本的方法,您可以將鍵的自定義一對一轉換應用於字符串,例如${x}_${y}
(依賴於特定的鍵結構)或JSON.stringify(key)
(更通用)——這絕不是一個完美的解決方案,但在許多情況下它是最可靠的。
我知道 OP 要求使用其他方法,但我認為這里仍然需要提到這個方法,作為標題問題的最直接答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.