Using An Array As A Key In A JavaScript Map

JavaScript

22/12/2022


Unlike regular objects, Maps in JavaScript allow you to use any key type for your key value pairs.

JAVASCRIPT
// Using an Array as a key fails
const regularObject = {
["key1a", "key1b"]: "value", // Uncaught SyntaxError: missing ] in computed property name
}
const arrayKey = ["key1a", "key1b"]
const regularObject = {
arrayKey: "value",
}
// Variable name is turned into a string
for (const key in regularObject) {
console.log(`${key}:`, typeof key) // arrayKey: string
}
const mapObject = new Map()
mapObject.set(arrayKey, "value")
// Key remains an object
for (const key in mapObject.keys()) {
console.log(`${key}:`, typeof key) // key1a,key1b: object
}

As the example above 👆 shows, using an Array in an object literal will simply fail or, in the case of a variable, convert the variable name into a string.

Caveat

This sounds great at first! 🤩 You can easily fetch the value with the appropriate object.

JAVASCRIPT
mapObject.get(arrayKey) // "value"

However, the key works by reference! This means you need to use the same object reference to retrieve the same value! As such, if you were to use a "different" Array, even with the same values, you would retrieve undefined.

JAVASCRIPT
const mapObject = new Map()
mapObject.set(["key1a", "key1b"], "value")
mapObject.get(["key1a", "key1b"]) // undefined

This makes Maps initially more difficult to use as you may not be able to save a reference to the original object that you used as a key.

Solution

How do we solve this? 🤔 You may resort to using a string by joining the elements of your Array.

JAVASCRIPT
const mapObject = new Map()
mapObject.set(["key1a", "key1b"].join("::"), "value")
mapObject.get(["key1a", "key1b"].join("::")) // "value"

However, this is only recommended if your Array only contains primitive types and if you know for CERTAIN that your separator (in this example ::) does NOT appear in your Array.

If that is not the case, I recommend using a library such as array-keyed-map where someone already figured out the problem.


WRITTEN BY

Code and stuff