Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const MultiKeyMap = (() => {
- const symbols = {
- checkKeyLength: Symbol('checkKeyLength'),
- keyCount: Symbol('keyCount'),
- data: Symbol('data')
- }
- /**
- * @throws {NotEnoughKeys} When the list of keys given to a method is too short.
- * @throws {TooManyKeys} When the list of keys given to a method is too long.
- * @throws {KeyIsNotPresent} When no value was found in the get method.
- */
- class MultiKeyMap {
- /**
- * Constructs a new map with the given number of keys.
- * @param {number} n The number of keys.
- */
- constructor (n) {
- this[symbols.keyCount] = n
- this[symbols.data] = {}
- }
- [symbols.checkKeyLength] (n) {
- if (n < this[symbols.keyCount]) {
- throw Error(`Not enough keys. Expected ${this[symbols.keyCount]}, received ${n}.`)
- }
- if (n > this[symbols.keyCount]) {
- throw Error(`Too many keys. Expected ${this[symbols.keyCount]}, received ${n}.`)
- }
- }
- /**
- * Assigns the specified value to the given keys.
- * @param keys {string[]} An array of length n containing stringifiable items where n is the number of keys in the map.
- * @param value {*} The actual value.
- */
- set (keys, value) {
- keys = JSON.parse(JSON.stringify(keys))
- this[symbols.checkKeyLength](keys.length)
- let currentData = this[symbols.data]
- while (keys.length > 1) {
- const currentKey = keys.shift()
- if (!(currentKey in currentData)) {
- currentData[currentKey] = {}
- }
- currentData = currentData[currentKey]
- }
- const currentKey = keys.shift()
- currentData[currentKey] = value
- }
- /**
- * Checks whether the map contains any value assigned to the given keys.
- * @param keys {string[]} An array of length n containing stringifiable items where n is the number of keys in the map.
- *
- * @return {boolean} Whether an assigned value was found or not.
- */
- contains (keys) {
- keys = JSON.parse(JSON.stringify(keys))
- this[symbols.checkKeyLength](keys.length)
- let currentData = this[symbols.data]
- while (keys.length > 1) {
- const currentKey = keys.shift()
- if (!(currentKey in currentData)) {
- return false
- }
- currentData = currentData[currentKey]
- }
- const currentKey = keys.shift()
- return (currentKey in currentData)
- }
- /**
- * Gets the value stored behind the given keys.
- * @param keys {string[]} An array of length n containing stringifiable items where n is the number of keys in the map.
- *
- * @return {*} The requested value.
- */
- get (keys) {
- keys = JSON.parse(JSON.stringify(keys))
- const keyString = keys.join(' - ')
- this[symbols.checkKeyLength](keys.length)
- let currentData = this[symbols.data]
- while (keys.length > 1) {
- const currentKey = keys.shift()
- if (!(currentKey in currentData)) {
- throw Error(`Key is not present in map. (${keyString})`)
- }
- currentData = currentData[currentKey]
- }
- const currentKey = keys.shift()
- if (!(currentKey in currentData)) {
- throw Error(`Key is not present in map. (${keyString})`)
- }
- return currentData[currentKey]
- }
- /**
- * Returns a stringified JSON representation of the map.
- * @return {string} Stringified JSON representation of the map.
- */
- stringify () {
- return JSON.stringify(this[symbols.data], null, 2)
- }
- }
- return MultiKeyMap
- })()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement