UNPKG

locutus

Version:

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

49 lines (48 loc) 1.75 kB
function normalizeMapEntries(mappings) { if (Array.isArray(mappings)) { if (mappings.every((entry) => Array.isArray(entry) && entry.length === 2)) { return mappings.map((entry) => [String(entry[0]), String(entry[1])]); } const out = []; for (let i = 0; i + 1 < mappings.length; i += 2) { out.push([String(mappings[i]), String(mappings[i + 1])]); } return out; } return Object.entries(mappings).map(([key, value]) => [String(key), String(value)]); } export function map(mappings, str) { // discuss at: https://locutus.io/tcl/map/ // parity verified: Tcl 8.6 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Applies key/value replacements in left-to-right single-pass order like Tcl string map. // example 1: map(['abc', 'X', 'a', 'Y'], 'abc abca') // returns 1: 'X XY' // example 2: map(['cat', 'dog', ' ', '_'], 'cat cat') // returns 2: 'dog_dog' // example 3: map(['ab', 'X', 'a', 'Y'], 'ababa') // returns 3: 'XXY' const source = String(str); const entries = normalizeMapEntries(mappings).filter(([key]) => key.length > 0); if (entries.length === 0) { return source; } let out = ''; let cursor = 0; while (cursor < source.length) { let matched = false; for (const [key, value] of entries) { if (source.startsWith(key, cursor)) { out += value; cursor += key.length; matched = true; break; } } if (!matched) { out += source[cursor]; cursor += 1; } } return out; }