UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

55 lines (54 loc) 1.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.assoc_in = assoc_in; function cloneForKey(value, nextKey) { if (Array.isArray(value)) { return value.slice(); } if (typeof value === 'object' && value !== null) { return { ...value }; } return typeof nextKey === 'number' ? [] : {}; } function assoc_in(value, keys, newValue) { // discuss at: https://locutus.io/clojure/assoc_in/ // parity verified: Clojure 1.12 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Immutably associates a value at a nested path, similar to Clojure assoc-in. // example 1: assoc_in({a: {b: 1}}, ['a', 'b'], 2) // returns 1: {a: {b: 2}} // example 2: assoc_in({a: {}}, ['a', 'c'], 10) // returns 2: {a: {c: 10}} // example 3: assoc_in([1, {x: 3}], [1, 'x'], 9) // returns 3: [1, {x: 9}] if (!Array.isArray(keys)) { return value; } if (keys.length === 0) { return newValue; } const root = cloneForKey(value, keys[0]); let sourceCursor = value; let targetCursor = root; for (let i = 0; i < keys.length - 1; i++) { const key = keys[i]; const nextKey = keys[i + 1]; if (key === undefined || nextKey === undefined) { continue; } const sourceNext = sourceCursor !== null && typeof sourceCursor === 'object' ? sourceCursor[key] : undefined; const clonedNext = cloneForKey(sourceNext, nextKey); targetCursor[key] = clonedNext; sourceCursor = sourceNext; targetCursor = clonedNext; } const leafKey = keys[keys.length - 1]; if (leafKey === undefined) { return root; } ; targetCursor[leafKey] = newValue; return root; }