UNPKG

immutable-class

Version:

A template for creating immutable classes

110 lines (109 loc) 3.12 kB
import hasOwnProp from 'has-own-prop'; import { SimpleArray } from '../simple-array/simple-array'; export class KeyedArray { constructor(keyGetter) { Object.defineProperty(this, "getKey", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.getKey = keyGetter; } static withKey(key) { return new KeyedArray((x) => x[key]); } get(array, key) { const { getKey } = this; return SimpleArray.find(array, x => getKey(x) === key); } toRecord(array) { const { getKey } = this; const myRecord = {}; for (const a of array) { const key = getKey(a); if (myRecord[key]) continue; myRecord[key] = a; } return myRecord; } checkValid(array, what, where) { const { getKey } = this; const seen = {}; for (const a of array) { const key = getKey(a); if (seen[key]) { throw new Error(['duplicate', what, `'${key}'`, where ? 'in' : undefined, where] .filter(Boolean) .join(' ')); } seen[key] = 1; } } isValid(array) { const { getKey } = this; const seen = {}; for (const a of array) { const key = getKey(a); if (seen[key]) return false; seen[key] = 1; } return true; } overrideByKey(things, thingOverride) { const { getKey } = this; const overrideKey = getKey(thingOverride); let added = false; things = things.map(t => { if (getKey(t) === overrideKey) { added = true; return thingOverride; } else { return t; } }); if (!added) things.push(thingOverride); return things; } overridesByKey(things, thingOverrides) { const { getKey } = this; const keyToIndex = {}; const thingsLength = things.length; for (let i = 0; i < thingsLength; i++) { keyToIndex[getKey(things[i])] = i; } const newThings = things.slice(); for (const thingOverride of thingOverrides) { const key = getKey(thingOverride); if (hasOwnProp(keyToIndex, key)) { newThings[keyToIndex[key]] = thingOverride; } else { newThings.push(thingOverride); } } return newThings; } dedupe(array) { const { getKey } = this; const seen = {}; return array.filter(a => { const key = getKey(a); if (seen[key]) { return false; } else { seen[key] = true; return true; } }); } deleteByKey(array, key) { const { getKey } = this; return array.filter(a => getKey(a) !== key); } }