- HashMap
- Parameters
- size
- length
- has
- get
- keyOf
- lastKeyOf
- optionalKeyOf
- optionalLastKeyOf
- optionalGet
- find
- findLast
- optionalFind
- optionalFindLast
- findKey
- findLastKey
- optionalFindKey
- optionalFindLastKey
- set
- emplace
- copy
- clone
- delete
- clear
- forEach
- forEachRight
- every
- some
- reduce
- reduceRight
- iterator
- entries
- entriesRight
- keys
- values
- keysRight
- valuesRight
- LinkedHashMap
- Option
- HashMap#overrideEquals
- HashMap#overrideHash
- HashMap#overrides
- HashMap#emplaceUpdate
- HashMap#emplaceInsert
- HashMap#emplaceHandler
- HashMap#ForEachCallback
- HashMap#MatchesPredicate
- HashMap#ReduceFunction
- isFunction
- isIterable
- isString
- sameValue
- sameValueZero
- abstractEquals
- strictEquals
- hammingWeight
- hash
- hashCodeFor
- equalsFor
- equalsAndHash
- some
- none
This HashMap is backed by a Hash array mapped trie.
copy
(Map | HashMap | LinkedHashMap | Iterable<Array<key, value>> | Object)?
Meta
- copyright: Jack Moxley https://github.com/jackmoxley
- author: Jack Moxley
Returns the number of elements in this hashmap.
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const size = hashmap.size;
console.log(size);
// logs: 3
Returns number the number of elements in the array
Returns the number of elements in this hashmap.
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const length = hashmap.length;
console.log(length);
// logs: 3
Returns number the number of elements in the array
- See: Map.has
Does the map have this key.
- return true if the
key
is in the map. - if no elements match, it returns false.
- it is legitimate for keys to be null or undefined.
Maps typically index keys, and so is generally a fast operation.
key
any the matching key we use to identify if we have a match.overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hash and equals methods, rather than them being looked up.
Does this contain a key that is there
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const hasResult = hashmap.has(1);
// hasResult === true
Does this contain a key that isn't there
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const hasResult = hashmap.has(4);
// hasResult === false
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const key = new NameKey('John','Smith');
const hasResult = hashmap.has(key);
// hasResult === true
Advanced: using a custom hash and equals, to determine if there are entries for a specific hash
const myHash = 3;
const hashEquals = {hash: myHash, equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const hasResult = hashmap.has(0, hashEquals);
// hasResult === true
// the hash of the number 3 is actually also 3. all 32 bit integers have the same hash.
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns boolean if it holds the key or not.
- See: Map.get
Get a value from the map using this key.
- return the first
value
from the[key,value]
pair that matches the key. - if no elements match, it returns undefined.
- it is legitimate for keys to be null or undefined, and if set, will find a value.
- it is also legitimate for values to be null or undefined, as such get should never be used as an existence check. {@see HashMap#optionalGet}
Also provides a way to override both the equals and the hash Performance:
- will be O(1) approaching O(log n)
key
any the matching key we use to identify if we have a match.overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up.
What is the value for a key
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.get(1);
// getResult === 'value1'
What is the value for a key that isn't there
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.get(4);
// getResult === undefined
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const key = new NameKey('John','Smith');
const getResult = hashmap.get(key);
// getResult === 'Librarian'
Advanced: using a custom hash and equals, to get the first entry for a specific hash
const myHash = 3;
const hashEquals = {hash: myHash, equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.get(0, hashEquals);
// getResult === 'value3'
// the hash of the number 3 is actually also 3. all 32 bit integers have the same hash.
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns any the value of the element that matches.
- See: Array.indexOf
Get the key from the map using the provided value. Since values are not hashed, this has to check each value in the map until a value matches, or the whole map, if none match. As such this is a slow operation. Performance O(n) as we have to iterate over the whole map, to find each value and perform an equality against it.
value
any The value we are searching the map foroverrides
HashMap#overrides<equals>? an optional override to allow a user to define the equals methods, rather than it being looked up on the value.
What is the key for a value
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const keyOfResult = hashmap.keyOf('value2');
// keyOfResult === 2
What is the value for a key that isn't there
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const keyOfResult = hashmap.keyOf('value4');
// keyOfResult === undefined
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const keyOfResult = hashmap.keyOf('Engineer');
// getResult ~ NameKey('Orlando','Keleshian')
Advanced: using a custom equals, to get the first key in the hashmap
const myEquals = {equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const keyOfResult = hashmap.keyOf(0, myEquals);
// keyOfResult === 1
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns (any | undefined) the first key for this value or undefined
- See: Array.lastIndexOf
Get the key from the map using the provided value, searching the map in reverse. Since values are not hashed, this has to check each value in the map until a value matches, or the whole map, if none match. As such this is a slow operation. Performance O(n) as we have to iterate over the whole map, to find each value and perform an equality against it.
value
any The value we are searching the map for, (in reverse)overrides
HashMap#overrides<equals>? an optional override to allow a user to define the equals methods, rather than it being looked up on the value.
What is the key for a value
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const lastKeyOfResult = hashmap.lastKeyOf('value2');
// lastKeyOfResult === 2
What is the value for a key that isn't there
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const lastKeyOfResult = hashmap.lastKeyOf('value4');
// lastKeyOfResult === undefined
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const lastKeyOfResult = hashmap.lastKeyOf('Engineer');
// getResult ~ NameKey('Orlando','Keleshian')
Advanced: using a custom equals, to get the last key in the hashmap
const myEquals = {equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const lastKeyOfResult = hashmap.lastKeyOf(0, myEquals);
// lastKeyOfResult === 3
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns (any | undefined) the last key for this value or undefined
- See: Option.some
- See: Option.none
- See: Array.indexOf
Get the key from the map using the provided value, and wrap it in an Option. Since values are not hashed, this has to check each value in the map until a value matches, or the whole map, if none match. As such this is a slow operation. Performance O(n) as we have to iterate over the whole map, to find each value and perform an equality against it.
value
any The value we are searching the map foroverrides
HashMap#overrides<equals>? an optional overrides to allow a user to define the equals methods, rather than it being looked up on the value.
What is the key for a value
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalKeyOfResult = hashmap.optionalKeyOf('value2');
// optionalKeyOfResult === Option.some(2)
What is the value for a key that isn't there
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalKeyOfResult = hashmap.optionalKeyOf('value4');
// optionalKeyOfResult === Option.none
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const optionalKeyOfResult = hashmap.optionalKeyOf('Engineer');
// getResult ~ Option.some(NameKey('Orlando','Keleshian'))
Advanced: using a custom equals, to get the first key in the hashmap
const myEquals = {equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalKeyOfResult = hashmap.optionalKeyOf(0, myEquals);
// optionalKeyOfResult === Option.some(1)
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns Option the first key for this value or none
- See: Option.some
- See: Option.none
- See: Array.lastIndexOf
Get the key from the map using the provided value, searching the map in reverse. Since values are not hashed, this has to check each value in the map until a value matches, or the whole map, if none match. As such this is a slow operation. Performance O(n) as we have to iterate over the whole map, to find each value and perform an equality against it.
value
any The value we are searching the map for, (in reverse)overrides
HashMap#overrides<equals>? an optional overrides to allow a user to define the equals methods, rather than it being looked up on the value.
What is the key for a value
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalLastKeyOfResult = hashmap.optionalLastKeyOf('value2');
// optionalLastKeyOfResult === Option.some(2)
What is the value for a key that isn't there
const hashmap = new LinkedHashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalLastKeyOfResult = hashmap.optionalLastKeyOf('value4');
// optionalLastKeyOfResult === Option.none
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const optionalLastKeyOfResult = hashmap.optionalLastKeyOf('Engineer');
// getResult ~ Option.some(NameKey('Orlando','Keleshian'))
Advanced: using a custom equals, to get the last key in the hashmap
const myEquals = {equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalLastKeyOfResult = hashmap.optionalLastKeyOf(0, myEquals);
// optionalLastKeyOfResult === Option.some(3)
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns Option the last key for this value or none
- See: Option.some
- See: Option.none
- See: Map.get
Get an optional value from the map. This is effectively a more efficent combination of calling has and get at the same time.
- return the first
some(value)
from the[key,value]
pair that matches - if no elements match, it returns
none()
. - it is legitimate for keys to be null or undefined, and if set, will still acknowledge it exists, against the key.
Maps typically index keys, and so is generally a fast operation.
key
any the key we use to identify if we have a match.overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up.
What is the value for a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.optionalGet(1);
// getResult === Option.some('value1') {value:'value1',has:true}
What is the value for a key that isn't there
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.optionalGet(4);
// getResult === Option.none {has:false}
What is the value for a key with an undefined value
const hashmap = new HashMap([[1,'value1'],[2,undefined],[3,'value3']]);
const getResult = hashmap.optionalGet(2);
// getResult === Option.some(undefined) {value:undefined,has:true}
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap([[new NameKey('John','Smith'),'Librarian'],[new NameKey('Orlando','Keleshian'),'Engineer']]);
const key = new NameKey('John','Smith');
const getResult = hashmap.optionalGet(key);
// getResult === Option.some('Librarian') {value:'Librarian',has:true}
Advanced: using a custom hash and equals, to get the first entry for a specific hash
const myHash = 3;
const hashEquals = {hash: myHash, equals: () => true}
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const getResult = hashmap.optionalGet(0, hashEquals);
// getResult === Option.some('value3') {value:'value3',has:true}
// the hash of the number 3 is actually also 3. all 32 bit integers have the same hash.
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns Option an optional result.
- See: Array.find
Find the first value in the map which passes the provided MatchesPredicate
.
- return the first
value
from the[key,value]
pair that matches - if no elements match, it returns undefined.
- if no predicate is defined, will return the first value it finds.
findPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>value
)thisArg
any? Value to use asthis
when executingfindPredicate
(optional, defaultundefined
)
Find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findResult = hashmap.find((value) => value.startsWith('val'));
// findResult === 'value1'
Can't find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findResult = hashmap.find((value) => value.startsWith('something'));
// findResult === undefined
Returns any the value of the element that matches.
- See: Array.find
Find the last value in the map which passes the provided MatchesPredicate
.
- return the last
value
from the[key,value]
pair that matches - if no elements match, it returns undefined.
- if no predicate is defined, will return the last value it finds. (It does this by iterating over the hashmap in reverse, and returning the first
item that matches)
findPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>value
)thisArg
any? Value to use asthis
when executingfindPredicate
(optional, defaultundefined
)
Find the last value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findLastResult = hashmap.findLast((value) => value.startsWith('val'));
// findLastResult === 'value3'
Can't find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findLastResult = hashmap.findLast((value) => value.startsWith('something'));
// findLastResult === undefined
Returns any the value of the element that matches.
- See: Option.some
- See: Option.none
- See: Array.find
Find the first value in the map which passes the provided MatchesPredicate
.
- return the first
value
from the[key,value]
pair that matches, wrapped in an Option - if no elements match, it returns none.
- if no predicate is defined, will return the first value it finds.
findPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>value
)thisArg
any? Value to use asthis
when executingfindPredicate
(optional, defaultundefined
)
Find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindResult = hashmap.optionalFind((value) => value.startsWith('val'));
// optionalFindResult.value === 'value1'
// optionalFindResult.has === true
Can't find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindResult = hashmap.optionalFind((value) => value.startsWith('something'));
// optionalFindResult.has === false
Returns (Option<any> | Option.none) the value of the element that matches.
- See: Option.some
- See: Option.none
- See: Array.find
Find the last value in the map which passes the provided MatchesPredicate
.
- return the last
value
from the[key,value]
pair that matches, wrapped in an Option - if no elements match, it returns none.
- if no predicate is defined, will return the last value it finds. (It does this by iterating over the hashmap in reverse, and returning the first
item that matches)
findPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>value
)thisArg
any? Value to use asthis
when executingfindPredicate
(optional, defaultundefined
)
Find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindLastResult = hashmap.optionalFindLast((value) => value.startsWith('val'));
// optionalFindLastResult.value === 'value3'
// optionalFindLastResult.has === true
Can't find a value
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindLastResult = hashmap.optionalFindLast((value) => value.startsWith('something'));
// optionalFindLastResult.has === false
Returns (Option<any> | Option.none) the value of the element that matches.
- See: Array.findIndex
Find the first key in the map which passes the provided MatchesPredicate
.
- return the first
key
from the[key,value]
pair that matches - if no elements match, it returns undefined.
- if no predicate is defined, will return the first key it finds.
findKeyPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>key
)thisArg
any? Value to use asthis
when executingfindKeyPredicate
(optional, defaultundefined
)
Find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findKeyResult = hashmap.findKey((value) => value.startsWith('val'));
// findKeyResult === 1
Can't find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findKeyResult = hashmap.findKey((value) => value.startsWith('something'));
// findKeyResult === undefined
Returns any the key of the element that matches..
Find the last key in the map which passes the provided MatchesPredicate
.
- return the last
key
from the[key,value]
pair that matches - if no elements match, it returns undefined.
- if no predicate is defined, will return the last key it finds. (It does this by iterating over the hashmap in reverse, and returning the first
item that matches)
findKeyPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>key
)thisArg
any? Value to use asthis
when executingfindKeyPredicate
(optional, defaultundefined
)
Find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findLastKeyResult = hashmap.findLastKey((value) => value.startsWith('val'));
// findLastKeyResult === 3
Can't find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const findLastKeyResult = hashmap.findLastKey((value) => value.startsWith('something'));
// findLastKeyResult === undefined
Returns any the key of the element that matches..
- See: Option.some
- See: Option.none
- See: Array.prototype.findIndex
Find the first key in the map which passes the provided MatchesPredicate
.
- return the first
key
from the[key,value]
pair that matches, wrapped in an Option - if no elements match, it returns none.
- if no predicate is defined, will return the first key it finds.
findKeyPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>key
)thisArg
any? Value to use asthis
when executingfindKeyPredicate
(optional, defaultundefined
)
Find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindKeyResult = hashmap.optionalFindKey((value) => value.startsWith('val'));
// optionalFindKeyResult.value === 1
// optionalFindKeyResult.has === true
Can't find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindKeyResult = hashmap.optionalFindKey((value) => value.startsWith('something'));
// optionalFindKeyResult.has === false
Returns (Option<any> | Option.none) the key of the element that matches.
- See: Option.some
- See: Option.none
- See: Array.prototype.findIndex
Find the last key in the map which passes the provided MatchesPredicate
.
- return the last
key
from the[key,value]
pair that matches, wrapped in an Option - if no elements match, it returns none.
- if no predicate is defined, will return the last key it finds. (It does this by iterating over the hashmap in reverse, and returning the first
item that matches)
findKeyPredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>key
)thisArg
any? Value to use asthis
when executingfindKeyPredicate
(optional, defaultundefined
)
Find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindLastKeyResult = hashmap.optionalFindLastKey(value) => value.startsWith('val'));
// optionalFindLastKeyResult.value === 3
// optionalFindLastKeyResult.has === true
Can't find a key
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const optionalFindLastKeyResult = hashmap.optionalFindLastKey((value) => value.startsWith('something'));
// optionalFindLastKeyResult.has === false
Returns (Option<any> | Option.none) the key of the element that matches.
- See: Map.prototype.set
Sets a value onto this map, using the key as its reference.
- If the key already exists, this will overwrite the value with the new value.
- If it doesn't exist it adds the new key value pair to the map.
- NB: Ordering in a HashMap is not defined by insertion order (much), but by hash value (mostly).
key
any the key we want to key our value tovalue
any the value we are settingoverrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up.
set a value
const hashmap = new HashMap();
hashmap.set(1,'value1');
const hasResult = hashmap.has(1);
// hasResult === true
overwrite a value
const hashmap = new HashMap([[1,'value1'],[2,'value2']]);
hashmap.set(2,'other');
const getResult = hashmap.get(2);
// getResult === 'other'
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const hashmap = new HashMap();
hashmap.set(new NameKey('John','Smith'),'Librarian');
const hasResult = hashmap.has(new NameKey('John','Smith'));
// hasResult === true
Advanced: using a custom hash and equals, to set a value to a specific hash
const hashmap = new HashMap();
hashmap.set(1,'value1', {hash: 3});
const hasResult = hashmap.has(3, {equals: () => true} );
// hasResult === true
// the hash of the number 3 is actually also 3. all 32 bit integers have the same hash.
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
Returns HashMap this hashmap
- See: upsert proposal
- See: Map.prototype.emplace
Given a key and a handler object, the emplace method will either remap an existing entry, insert a new entry from a mapping function, or both. emplace will return the updated or inserted value.
key
any the key we want to key our value tohandler
HashMap#emplaceHandler<insert, update> the insert and update methods we want to use.overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up.
insert into the map
const hashmap = new HashMap();
const handler = {
update: () => {
return 'update';
},
insert: (key, map) => {
return 'insert';
}
};
const ret = hashmap.emplace('key', handler)
// hashmap = [['key', 'insert']]
// ret === 'insert'
update the map
const hashmap = new HashMap([['key','value']]);
const handler = {
update: () => {
return 'update';
},
insert: (key, map) => {
return 'insert';
}
};
const ret = hashmap.emplace('key', handler)
// hashmap = [['key', 'update']]
// ret === 'update'
insert into the map if the key already exists without an update
const hashmap = new HashMap([['key','value']]);
const handler = {
insert: (key, map) => {
return 'insert';
}
};
const ret = hashmap.emplace('key', handler)
// hashmap = [['key', 'value']]
// ret === 'value'
update into the map without an insert method (throws an error)
const hashmap = new HashMap([['key','value']]);
const handler = {
update: (oldValue, key, map) => {
return 'update';
}
};
hashmap.emplace('key', handler)
// throws an Error as insert doesn't exist
// hashmap = [['key', 'value']]
Advanced: using a predefined hashCode and equals on the key
class NameKey {
constructor(firstName, secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
hashCode() {
return (Mootable.hash(firstName) * 31) +Mootable.hash(secondName);
}
equals(other) {
return other && other instanceof NameKey && other.firstName === this.firstName && other.secondName === this.secondName;
}
}
const handler = {
insert: (key, map) => {
return 'Librarian';
}
};
const hashmap = new HashMap();
const ret = hashmap.emplace(new NameKey('John','Smith'),handler);
// ret === 'Librarian'
Advanced: using a custom hash and equals, to emplace a value to a specific hash
const handler = {
insert: (key, map) => {
return 'value1';
}
};
const hashmap = new HashMap();
const ret = hashmap.emplace(1,handler, {hash: 3});
// ret === 'value1'
// the hash of the number 3 is actually also 3. all 32 bit integers have the same hash.
// 0 doesn't exist in the hashMap, but we are circumventing using the key entirely.
- Throws Error if the insert method does not exist, and it can't find the key.
Returns any the new value that was set, or overwrote.
Copies all the entries from the map, array or iterable, into this hashmap.
other
(Map | HashMap | LinkedHashMap | Iterable<Array<key, value>> | Object) the iterable to copy
copy into the HashMap from an array of key value pairs
const hashmap = new HashMap([['key0','value0']]);
const arr = [[1,'value1'],[2,'value2'],[3,'value3']];
hashmap.copy(arr);
// hashmap.size === 4;
copy into the HashMap from another map
const hashmap = new HashMap([['key0','value0']]);
const map = new Map([[1,'value1'],[2,'value2'],[3,'value3']])
hashmap.copy(map);
// hashmap.size === 4;
copy into the HashMap from another HashMap
const first = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']])
const hashmap = new HashMap(first);
// hashmap.size === 3;
copy into the HashMap from a class with symbol iterator
const hashmap = new HashMap([['key0','value0']]);
class MyIterable = {
*[Symbol.iterator] () {
yield ["key1", "value1"];
yield ["key2", "value2"];
yield ["key3", "value3"];
yield ["key4", "value4"];
}
}
const iterable = new MyIterable();
hashmap.copy(iterable);
// hashmap.size === 5;
// it doesn't have to be a generator, an iterator works too.
copy into the HashMap from an object with an entries generator function
const hashmap = new HashMap([['key0','value0']]);
const entriesObj = {
entries: function* () {
yield ["key1", "value1"];
yield ["key2", "value2"];
yield ["key3", "value3"];
yield ["key4", "value4"];
}
}
hashmap.copy(entriesObj);
// hashmap.size === 5;
// it doesn't have to be a generator, an iterator works too.
copy into the HashMap from an object with a forEach function
const hashmap = new HashMap([['key0','value0']]);
const forEachObj = {
forEach: (callback, ctx) => {
for (let i = 1; i <= 4; i++) {
callback.call(ctx, 'value' + i, 'key' + i);
}
}
};
hashmap.copy(forEachObj);
// hashmap.size === 5;
- Throws TypeError if the provided object other is null or not iterable.
Returns HashMap this hashmap, with the values copied to it.
Makes a full copy of this hashmap and returns the clone.
Returns HashMap
Deletes an entry from this hashmap, using the provided key
key
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Clears the data from this hashmap. All data is orphaned, and will be Garbage Collected.
Returns HashMap this hashmap
Execute the provided callback on every [key,value]
pair of this map iterable.
callback
HashMap#ForEachCallback (optional, default(value,key,map)=>{}
)thisArg
any? Value to use asthis
when executingforEachCallback
Log all the keys and values.
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
mapIterable.forEach((value) => console.log(key, value));
// will log to the console:
// 1 value1
// 2 value2
// 3 value3
// Ordering is deterministic on paper, but from a usability point of view effectively random
// as it is ordered by a mix of the hash of the key, and order of insertion.
Returns HashMap the hashmap you are foreaching on..
Execute the provided callback on every [key,value]
pair of this map iterable in reverse.
callback
HashMap#ForEachCallback (optional, default(value,key,map)=>{}
)thisArg
any? Value to use asthis
when executingforEachCallback
Log all the keys and values.
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
mapIterable.forEachRight((value) => console.log(key, value));
// will log to the console:
// 3 value3
// 2 value2
// 1 value1
// Ordering is deterministic on paper, but from a usability point of view effectively random
// as it is ordered by a mix of the hash of the key, and order of insertion.
Returns HashMap the hashmap you are foreaching on..
- See: Array.every
Test to see if ALL elements pass the test implemented by the passed MatchesPredicate
.
- if any element does not match, returns false
- if all elements match, returns true.
- if no elements match, returns false.
- if the iterable is empty, returns true. (irrespective of the predicate)
- if no predicate is provided, returns true.
everyPredicate
HashMap#MatchesPredicate if the provided function returnsfalse
, at any point theevery()
function returns false. (optional, default(value,key,iterable)=>true
)thisArg
any? Value to use asthis
when executingeveryPredicate
(optional, defaultundefined
)overrides
HashMap#overrides<reverse>? a set of optional overrides to allow a user to define whether to search in reverse (optional, defaultundefined
)
Do all values start with 'value'. (yes)
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const everyResult = hashmap.every((value) => value.startsWith('value'));
// everyResult === true
Do all values start with value. (no)
const hashmap = new HashMap([[1,'value1'],[2,'doesntStart'],[3,'value3']]);
const everyResult = hashmap.every((value) => value.startsWith('value'));
// everyResult === false
Returns boolean true if all elements match, false if one or more elements fails to match.
- See: Array.some
Test to see if ANY element pass the test implemented by the passed MatchesPredicate
.
- if any element matches, returns true.
- if all elements match returns true.
- if no elements match returns false.
- if the iterable is empty, returns true.
- if no predicate is provided, returns true.
somePredicate
HashMap#MatchesPredicate the predicate to identify if we have a match. (optional, default(value,key,iterable)=>true
)thisArg
any? Value to use asthis
when executingsomePredicate
(optional, defaultundefined
)overrides
HashMap#overrides<reverse>? a set of optional overrides to allow a user to define whether to search in reverse (optional, defaultundefined
)
Do any values start with value. (yes all of them)
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const someResult = hashmap.some((value) => value.startsWith('value'));
// someResult === true
Do any values start with value. (yes 2 of them)
const hashmap = new HashMap([[1,'value1'],[2,'doesntStart'],[3,'value3']]);
const someResult = hashmap.some((value) => value.startsWith('value'));
// someResult === true
Returns boolean true if all elements match, false if one or more elements fails to match.
- See: Array.reduce
if initial value is
undefined
ornull
, unlike Array.reduce, no error occurs, and it is simply passed as the accumulator value
Iterate through the map reducing it to a single value.
reduceFunction
HashMap#ReduceFunction the predicate to identify if we have a match.initialValue
any? the initial value to start on the reduce.thisArg
any? Value to use asthis
when executingreduceFunction
add all the keys
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const reduceResult = hashmap.reduce((accumulator, value, key) => accumulator+key, 0);
// reduceResult === 6
add all the values into one string in reverse order
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const reduceResult = hashmap.reduce((accumulator, value) => value+accumulator, '');
// reduceResult === 'value3value2value1'
Returns any the final accumulated value.
- See: Array.reduceRight
if initial value is
undefined
ornull
, unlike Array.reduceRight, no error occurs, and it is simply passed as the accumulator value
Iterate backwards through the map reducing it to a single value.
reduceFunction
HashMap#ReduceFunction the predicate to identify if we have a match.initialValue
any? the initial value to start on the reduce.thisArg
any? Value to use asthis
when executingreduceFunction
add all the keys
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const reduceResult = hashmap.reduceRight((accumulator, value, key) => accumulator+key, 0);
// reduceResult === 6
add all the values into one string in reverse order
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
const reduceResult = hashmap.reduceRight((accumulator, value) => value+accumulator, '');
// reduceResult === 'value1value2value3'
Returns any the final accumulated value.
Iterates over all the entries in the map.
iterate over the map
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for ([key, value] of hashmap) {
console.log(key,value);
}
// logs:
// 1 value1
// 2 value2
// 3 value3
Iterates over all the entries in the map.
iterate over the map
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for ([key, value] of hashmap.entries()) {
console.log(key,value);
}
// logs:
// 1 value1
// 2 value2
// 3 value3
Iterates over all the entries in the map in reverse.
iterate over the map in reverse
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for ([key, value] of hashmap.entriesRight()) {
console.log(key,value);
}
// logs:
// 3 value3
// 2 value2
// 1 value1
Iterates over all the keys in the map.
iterate over the keys
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for (const key of hashmap.keys()) {
console.log(key);
}
// logs:
// 1
// 2
// 3
Iterates over all the values in the map.
iterate over the values
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for (const value of hashmap.values()) {
console.log(value);
}
// logs:
// value1
// value2
// value3
Iterates over all the keys in the map in reverse.
iterate over the keys
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for (const key of hashmap.keysRight()) {
console.log(key);
}
// logs:
// 3
// 2
// 1
Iterates over all the values in the map in reverse.
iterate over the values
const hashmap = new HashMap([[1,'value1'],[2,'value2'],[3,'value3']]);
for (const value of hashmap.valuesRight()) {
console.log(value);
}
// logs:
// value3
// value2
// value1
Extends HashMap
HashMap - LinkedHashMap Implementation for JavaScript
copy
(Map | HashMap | LinkedHashMap | Iterable<Array<key, value>> | Object)?
Meta
- copyright: Jack Moxley https://github.com/jackmoxley
- author: Jack Moxley
Returns HashMap
key
value
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns LinkedHashMap
key
handler
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns any
key
value
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns LinkedHashMap
key
handler
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns any
key
value
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns LinkedHashMap
key
handler
overrides
HashMap#overrides<equals, hash>? a set of optional overrides to allow a user to define the hashcode and equals methods, rather than them being looked up. * @return {HashMap}
Returns any
Returns (undefined | any)
Returns (undefined | any)
Returns (undefined | any)
Returns (undefined | any)
Returns Option
Returns Option
Returns (undefined | any)
Returns (undefined | any)
Returns Option
Returns Option
Returns LinkedHashMap
Makes a copy of this LinkedHashMap
Returns LinkedHashMap
Iterates over all the entries in the map.
Iterates over all the entries in the map.
Iterates over all the entries in the map in reverse order.
Iterates over all the keys in the map.
Iterates over all the values in the map.
Iterates over all the keys in the map in reverse.
Iterates over all the values in the map in reverse.
Option - a class to get round nullable fields.
has
whether it contains a value or not.value
the value to set
iterating over some
const opt = Option.some("hello");
for (value of opt) {
// loops once.
console.log(opt);
}
console.log("world");
// logs - hello\nworld
iterating over none
const opt = Option.none;
for (value of opt) {
// does not loop.
console.log(opt);
}
console.log("world");
// logs - world
Meta
- copyright: Jack Moxley https://github.com/jackmoxley
- author: Jack Moxley
Return the size of this option.
- 1 if it has a value
- 0 if it doesn't
Returns number
Provides an iterable for the Option If using a for loop.
- If it has a value the loop will execute just once.
- If it doesn't have a value the loop will not execute
iterating over some
const opt = Option.some("hello");
for (value of opt) {
// loops once.
console.log(opt);
}
console.log("world");
// logs - hello\nworld
iterating over none
const opt = Option.none;
for (value of opt) {
// does not loop.
console.log(opt);
}
console.log("world");
// logs - world
Returns Generator<any, void, any>
A constant representation of an Option with nothing in it: {value:undefined,has:false}
Type: Option
create an option using none
const option = Option.none;
// option.has === false
// option.value === undefined
// option.size === 0
When called with a value returns an Option object of the form: {value:value,has:true}
Even if a value is not provided it still counts as existing, this is different from other libraries,
we are effectively saying, null and undefined count as valid values.
value
the value
create an option using some
const myValue = 'hello';
const option = Option.some(myValue);
// option.has === true
// option.value === 'hello'
// option.size === 1
Returns Option the option in the form {value:value,has:true}
User Defined Equals Method A user defined function to define an equals method against 2 keys.
Type: Function
firstKey
any the first key.secondKey
any the second key
Returns boolean is it equal or not
User Defined Hash Method A user defined function to describe how to hash a key.
Type: Function
key
any the first key.
Returns number a 32 bit integer as a hash.
User defined hashing and equals methods HashMap will find the best fit for your objects, and if your keys themselves have the appropriate methods, then it will use them. However if you want to override that functionality this object allows you to do it. Not all functions and properties are used in every function, please refer to that function for details. If a function in future chooses to use one of the other properties or functions, it will NOT be marked as a breaking change. So be explicit.
Type: Object
hash
(number | HashMap#overrideHash)? The overriding hash value, or method to use.equals
HashMap#overrideEquals? The overriding equals method to usereverse
boolean? whether to search in reverse.
Emplace Update Method A user defined method to describe how to update our map.
Type: Function
oldValue
any the oldValue to update.key
any the key to the entry.map
HashMap the hashmap.
Returns any the new value to update the map with.
Emplace Insert Method A user defined method to describe how to insert into our map.
Type: Function
key
any the key to the entry.map
HashMap the hashmap.
Returns any the new value we want to insert.
Emplace handler methods
- Let M be this hashmap.
- For each Record { [[Key]], [[Value]] } e that is an element of entries, do
- If Equal(e.[[Key]], key) is true, then
- If HasProperty(handler, "update") is true, then
- Let updateFn be ? Get(handler, "update").
- Let updated be ? Call(updateFn, handler, « e.[[Value]], key, M »).
- Set e.[[Value]] to updated.
- Return e.[[Value]].
- Let insertFn be ? Get(handler, "insert").
- Let inserted be ? Call(insertFn, handler, « e.[[Value]], key, M »).
- Set e.[[Value]] to inserted.
- Return e.[[Value]].
Type: Object
update
HashMap#emplaceUpdate? The update method to use.insert
HashMap#emplaceInsert? The insert method to use
For Each Function
A callback to execute on every [key,value]
pair of this map iterable.
Type: Function
value
any? the entry value.key
any? the entry keymap
HashMap? the calling Map Iterable.
log the keys and values
const forEachFunction = (value, key) => console.log(key,value)
Test each element of the map to see if it matches and return
- true if the key and value match.
- false if it doesn't.
Type: Function
value
any? the entry value.key
any? the entry keyiterable
HashMap? the HashMap.
Only match keys divisible by 2
const myMatchPredicate = (value, key) => key % 2 === 0;
Only match values which are equal to another key in the map
const myMatchPredicate = (value, key, mapIterable) => mapIterable.has(value);
An alternative implementation, (but potentially slower, and assumes no undefined value)
const myMatchPredicate = (value, key, mapIterable) => mapIterable.indexOf(key) !== undefined;
Returns boolean a value that coerces to true if it matches, or to false otherwise.
- See: Array.reduce
Reduce Function
A callback to accumulate values from the HashMap [key,value]
into a single value.
Type: Function
accumulator
any? the value from the last execution of this function.value
any? the entry value.key
any? the entry keyhashmap
HashMap? the calling HashMap.
add all the keys
const reduceFunction = (accumulator, value, key) => accumulator+key
Returns any [accumulator] - the value to pass to the next time this function is called or the final return value.
Is the passed value not null and a function
func
(function | any) the function/object to test
test if its a function
const myFunc = () => 1 + 1;
Mootable.isFunction(myFunc) === true;
test if its not a function
const notAFunction = {};
Mootable.isFunction(notAFunction) === false;
test if its null
const notAFunction = null;
Mootable.isFunction(notAFunction) === false;
Returns boolean true if this is function and not null.
Is the passed object iterable and not null, i.e. it has a function that has a type of [Symbol.iterator]
iterable
(Iterable | any) the object to test
test if its iterable
class MyIterable {
* [Symbol.iterator]() {
yield 1;
}
}
Mootable.isIterable(new MyIterable()) === true;
test if its not an iterable
const notAnIterable = {};
Mootable.isIterable(notAnIterable) === false;
test if its null
const notAnIterable = null;
Mootable.isIterable(notAnIterable) === false;
Returns boolean true if this has a Symbol.iterator function
Is the passed value is not null and is a string
str
(string | any) the string/object to test
test if its iterable
const myString = "hello world";
Mootable.isString(myString) === true;
test if its not an iterable
const notAString = {};
Mootable.isString(notAString) === false;
test if its null
const notAString = null;
Mootable.isString(notAString) === false;
Returns boolean true if this is a string
- See: sameValue
sameValue is the result of Object.is. The only difference between sameValue and sameValueZero is that +0 and -0 are considered different with sameValue.
x
the first object to comparey
the second object to compare
Returns boolean if they are equals according to ECMA Spec for Same Value
- See: saveValueZero
sameValueZero is the equality method used by Map, Array, Set etc. The only difference between === and sameValueZero is that NaN counts as equal on sameValueZero
x
the first object to comparey
the second object to compare
Returns boolean if they are equals according to ECMA Spec for Same Value Zero
- See: abstractEquals
The abstract Equals method ==
.
Simply does an abstract equality comparison ==
against 2 values
x
the first object to comparey
the second object to compare
Returns boolean if they are equals according to ECMA Spec for Abstract Equality
- See: strictEquals
The strict Equals method ===
.
Simply does a strict equality comparison ===
against 2 values
x
the first object to comparey
the second object to compare
Returns boolean if they are equals according to ECMA Spec for Strict Equality
- See: hammingWeight
Counts the number of ones in a binary representation of a 32 bit integer.
flags
number 32 bit integer
count the number of bits set to one for the value 22
const myNumber = 22; // 10110 in binary
Mootable.hammingWeight(myNumber) === 3;
count the number of bits set to one for the value 12947
const myNumber = 12947; // 11001010010011 in binary
Mootable.hammingWeight(myNumber) === 7;
Returns number amount of ones.
Modified Murmur3 hash generator, with capped lengths. This is NOT a cryptographic hash, this hash is designed to create as even a spread across a 32bit integer as is possible.
key
the string being hashedlen
the max limit on the number of characters to hash (optional, default0
)seed
an optional random seed, or previous hash value to continue hashing against. (optional, default0
)
Returns number the hash
Given any object return back a hashcode
- If the key is undefined, null, false, NaN, infinite etc then it will be assigned a hash of 0.
- If it is a primitive such as string, number bigint it either take the numeric value, or the string value, and hash that.
- if it is a function, symbol or regex it hashes their string values.
- if it is a date, it uses the time value as the hash.
Otherwise
- If it has a hashCode function it will execute it, passing the key as the first and only argument. It will call this function again on its result.
- If it has a hashCode attribute it will call this function on it.
- If it can't do any of the above, it will assign a randomly generated hashcode, to the key using a hidden property.
As with all hashmaps, there is a contractual equivalence between hashcode and equals methods, in that any object that equals another, should produce the same hashcode.
key
any the key to get the hash code from
Returns number the hash code.
Given a key, produce an equals method that fits the hashcode contract.
- In almost all cases it will return with ECMASpec sameValueZero method. As is the case with native map, set and array.
- If it is a regex, it compares the type, and the string values.
- If it is a date, it compares the type, and the time values.
- If it is an option, it compares if they both have values, and then the values.
- If it has an equals function and that equals function when comapring 2 keys, return true. then it will use that.
- The function can either be in the form
key.equals(other)
, orkey.equals(other,key)
in the case of static-like functions.
- The function can either be in the form
The expectation and requirement is this key will always be the first argument to the method, the behaviour maybe unexpected if parameters are reversed.
As with all hashmaps, there is a contractual equivalence between hashcode and equals methods, in that any object that equals another, should produce the same hashcode.
key
any the key to get the hash code from
Returns (function (any, any): boolean) an equals function for 2 keys.
Given any object return back a hashcode
- If the key is undefined, null, false, NaN, infinite etc then it will be assigned a hash of 0.
- If it is a primitive such as string, number bigint it either take the numeric value, or the string value, and hash that.
- if it is a function, symbol or regex it hashes their string values.
- if it is a date, it uses the time value as the hash.
Otherwise
- If it has a hashCode function it will execute it, passing the key as the first and only argument. It will call this function again on its result.
- If it has a hashCode attribute it will call this function on it.
- If it can't do any of the above, it will assign a randomly generated hashcode, to the key using a hidden property.
As with all hashmaps, there is a contractual equivalence between hashcode and equals methods, in that any object that equals another, should produce the same hashcode.
key
any the key to get the hash code fromoptions
Returns {hash: number, equals: function} the hash code and equals function.
A function that when called with a value returns an Option object of the form: {value:value,has:true}
Even if a value is not provided it still counts as existing, this is different from other libraries,
we are effectively saying that null and undefined count as valid values.
Type: function (any?): Option
value
create an option using some
const myValue = 'hello';
const option = some(myValue);
// option.has === true
// option.value === 'hello'
// option.size === 1
A constant representation of an Option with nothing in it: {value:undefined,has:false}
Type: Option
create an option using none
const option = none;
// option.has === false
// option.value === undefined
// option.size === 0
The MIT License (MIT)
Copyright (c) 2021 Jack Moxley
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF