Last active
June 5, 2020 16:32
-
-
Save paceaux/11c5b06d16abba4d45571e1d10174938 to your computer and use it in GitHub Desktop.
SearchMap: A JavaScript Map with searchable keys
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Evaluates an array, makes the key lowercasee and makes the value an object with original keyname | |
* @param {Array} iterable=[] an array of arrays:[[key,val],[key,val]] | |
* @returns Array | |
*/ | |
function LowercaseIterable(iterable = []) { | |
if (iterable.length === 0) return []; | |
const newIterable = iterable.map(([key, val]) => { | |
const entry = [ | |
key.toLowerCase(), | |
{ originalKeyName: key, value: val } | |
]; | |
return entry; | |
}); | |
return newIterable; | |
} | |
/** | |
* @extends Map | |
* @classdesc Makes it possible to do a case insensitive search of a map by key | |
* @namespace SearchableKeyMap | |
* @property {Map} originalMap the original, unchanged map | |
*/ | |
class SearchableKeyMap extends Map { | |
/** | |
* @param {Iterable} iterable an array of arrays: [[key,val], [key,val]] | |
*/ | |
constructor(iterable) { | |
super(LowercaseIterable(iterable)); | |
this.originalMap = new Map(iterable); | |
} | |
/** Determines if any of SearchableKeyMap's keys contain a substring | |
* @param {string} searchKey | |
* | |
* @returns {Boolean} | |
*/ | |
containsKey(searchKey) { | |
const searchKeyName = searchKey.toLowerCase(); | |
const entries = this.entries(); | |
let result = false; | |
let nextEntry = entries.next(); | |
while (!nextEntry.done) { | |
const key = nextEntry.value[0]; | |
if (key.includes(searchKeyName)) { | |
result = true; | |
break; | |
} | |
nextEntry = entries.next(); | |
} | |
return result; | |
} | |
/** Searches in a map for a single key containing a substring | |
* @param {string} searchKey | |
* | |
* @returns string. First result it finds | |
*/ | |
getKeyContaining(searchKey) { | |
const searchKeyName = searchKey.toLowerCase(); | |
const entries = this.entries(); | |
let result; | |
let nextEntry = entries.next(); | |
while (!nextEntry.done) { | |
const [key] = nextEntry.value; | |
if (key.includes(searchKeyName)) { | |
result = key; | |
break; | |
} | |
nextEntry = entries.next(); | |
} | |
return result; | |
} | |
/** Searches for keys in a map that contain a substring * | |
* @param {string} searchKey | |
* | |
* @returns array | |
*/ | |
getKeysContaining(searchKey) { | |
const result = []; | |
const searchKeyName = searchKey.toLowerCase(); | |
const entries = this.entries(); | |
let nextEntry = entries.next(); | |
while (!nextEntry.done) { | |
const [key] = nextEntry.value; | |
if (key.includes(searchKeyName)) { | |
result.push(key); | |
} | |
nextEntry = entries.next(); | |
} | |
return result; | |
} | |
/** Creates a SearchableKeyMap of keys based on a search string | |
* @param {string} keyName key to search for | |
* | |
* @returns SearchableKeyMap | |
*/ | |
mapFromKeysContaining(keyName) { | |
if (!keyName) throw new Error('Keyname not provided'); | |
const newMap = new SearchableKeyMap(); | |
const searchKeyName = keyName.toLowerCase(); | |
const keys = this.getKeysContaining(searchKeyName); | |
keys.forEach((key) => { | |
const { originalKeyName, value } = this.get(key); | |
newMap.set(originalKeyName, value); | |
}); | |
return newMap; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment