
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
array-keyed-map
Advanced tools
A map data structure (a.k.a. associative array, dictionary) which maps from
arrays of arbitrary values ("paths") to arbitrary values. Like if the JS
built-in Map
took arrays as keys. Uses the key objects' identities;
does not stringify anything, because that way lies madness.
const ArrayKeyedMap = require('array-keyed-map')
const m = new ArrayKeyedMap()
const obj = { x: true }
const objIdentical = { x: true }
const fun = function() {}
const reg = /regexp/
// Set values
m.set([obj], 1)
m.set([obj, fun], 2)
m.set([reg, reg, true], 3)
m.set([], 4)
// Get values
console.log( m.get([obj]) ) // => 1
console.log( m.get([objIdentical]) ) // => undefined
console.log( m.get([obj, fun]) ) // => 2
console.log( m.get([reg, reg, true]) ) // => 3
console.log( m.get([]) ) // => 4
Features:
Map
, with the only API difference
of not iterating in insertion order.new ArrayKeyedMap([iterable])
Arguments:
iterable
: any iterable value of [key, value]
entries from
which to initialise contentsReturns ArrayKeyedMap akmap
.
Array keyed maps are iterable, so you can use them in for
-loops, pass them to
Array.from
, pass them into the constructor to create a copy (let copy = new ArrayKeyedMap(akmap)
), etc. (See .entries
.)
akmap.set(array, value)
Arguments:
array
: Array
of valuesvalue
: any valueSets the value for the given array.
Objects in the array are treated by identity. The identity of the array object itself is irrelevant.
Returns ArrayKeyedMap akmap
: a reference to the same map, handy for
chaining multiple .set
calls.
akmap.has(array)
Arguments:
array
: Array
of valuesReturns a Boolean: whether a previously set value exists for that key array.
akmap.get(array)
Arguments:
array
: Array
of valuesReturns the previously assigned value for this array, or undefined
otherwise.
akmap.delete(array)
Arguments:
array
: Array
of valuesDeletes the value at this exact array. Does not affect other array, even if they are prefixes or extensions of this one. Remember to do this if you no longer need a array: the keys and values are not automatically garbage-collected, even if the objects used as keys go out of scope!
Returns a Boolean: true
if an entry with that key existed and was
deleted, or false
if no such entry was found.
akmap.clear()
Deletes all entries from akmap
.
Returns undefined
.
akmap.hasPrefix(array)
Arguments:
array
: Array
of valuesReturns a Boolean: whether the map has some key starting with values matching the given array.
akmap.entries()
Returns an iterator that yields [key, value]
for every entry in akmap
.
:warning: Note that these are in arbitrary order; not insertion order!
This differs from the basic Map
!
akmap.keys()
Returns an iterator that yields the key part (type Array
) of each entry
in akmap
.
:warning: Note that these are in arbitrary order; not insertion order!
This differs from the basic Map
!
akmap.values()
Returns an iterator that yields the value part of each entry in akmap
.
:warning: Note that these are in arbitrary order; not insertion order!
This differs from the basic Map
!
akmap.forEach(callback[, thisArg])
Arguments:
callback
: Function
that will be called for each entry in akmap
,
passing the value, key, and map as arguments.thisArg
: Object
passed to the callback
as the value for
this
.Returns undefined
.
:warning: Note that these are in arbitrary order; not insertion order!
This differs from the basic Map
!
The paths are stored as a tree. If multiple paths are stored that share a
prefix, the prefix is not duplicated in storage, but shared between them.
For example: ['a', 'b']
and ['a', 'c']
have a shared prefix ['a']
.
Only 1 instance of 'a'
is stored, with 'b'
and 'c'
branching from it.
This means any operation involving a path scales linearly with that path's length, as it is traversed.
.size
is cached, so it does not traverse the data structure.
The algorithms are implemented iteratively, because the VM stack is faster than a JS stack.
.join('/')
β regular Map
?Because you might want your key array to contain objects (by identity) rather than strings, and objects cannot be stringified by identity, so identical objects would get mixed up. But this module can handle that:
let akmap = new ArrayKeyedMap()
// These are distinct paths!
const path1 = [{}, {}, {}]
const path2 = [{}, {}, {}]
akmap.set(path1, 1)
akmap.set(path2, 2)
console.log(akmap.get(path1)) // β 1
console.log(akmap.get(path2)) // β 2
Even if you only care about the object's content (and not identity), objects may contain cyclic references, which can't be stringified in isolation. But this module can handle that.
const akmap = new ArrayKeyedMap()
const cyclic = {}
// Contains a reference to itself. How would you stringify this?
cyclic.x = cyclic
akmap.set([ cyclic ], 1)
console.log(akmap.get([ cyclic ])) // β 1
Even if you are only using string keys, the separator you choose (e.g. /
)
may appear as part of your path elements, so the arrays ['a/b']
and
['a', 'b']
would both resolve to the key a/b
and overwrite each other.
So use a separator other than /
? Sure, but then you have the same
problem with elements possibly containing that.
So use a sufficiently long probabilistically unguessable separator like
03f2a8291a700b95904190583dba17c4ae1bf3bdfc2834391d60985ac6724940
? That
wastes RAM/disk. Also this is the code police speaking, you are under
assert for crimes against humanity, go to BSD jail.
So please use this module instead of a hack.
ES2015 I thinkβit uses
Map
s and
Symbol
s (β caniuse
links). At time of writing, it works in any recent Node.js or browser. Except
IE, of course.
Pull requests with improvements of any size are appreciated. If anything about the code or documentation is unclear, do ask.
To install the testing dependencies, run npm install
.
To run the automated tests and coding style check, run npm test
.
ISC.
FAQs
a map from arrays of values to values
The npm package array-keyed-map receives a total of 25,833 weekly downloads. As such, array-keyed-map popularity was classified as popular.
We found that array-keyed-map demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.