UNPKG

locutus

Version:

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

61 lines (60 loc) 2.3 kB
const expandTrSet = (pattern) => { const chars = [...pattern]; const expanded = []; for (let i = 0; i < chars.length; i += 1) { const startChar = chars[i]; if (startChar === undefined) { continue; } if (i + 2 < chars.length && chars[i + 1] === '-') { const endChar = chars[i + 2]; if (endChar !== undefined) { const startCode = startChar.codePointAt(0); const endCode = endChar.codePointAt(0); if (startCode !== undefined && endCode !== undefined) { const step = startCode <= endCode ? 1 : -1; for (let code = startCode; step > 0 ? code <= endCode : code >= endCode; code += step) { expanded.push(String.fromCodePoint(code)); } i += 2; continue; } } } expanded.push(startChar); } return expanded; }; export function tr(str, from, to) { // parity verified: Ruby 3.3 // discuss at: https://locutus.io/ruby/String/tr/ // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Transliterate characters from `from` set to `to` set. // note 2: Supports basic ranges like `a-z`; complement (`^`) is intentionally not implemented. // example 1: tr('hello', 'el', 'ip') // returns 1: 'hippo' // example 2: tr('abcxyz', 'a-z', 'A-Z') // returns 2: 'ABCXYZ' // example 3: tr('banana', 'an', 'o') // returns 3: 'booooo' const source = String(str); const fromChars = expandTrSet(String(from)); if (fromChars.length === 0) { return source; } const toChars = expandTrSet(String(to)); const map = new Map(); for (let index = 0; index < fromChars.length; index += 1) { const key = fromChars[index]; if (key === undefined) { continue; } const replacement = toChars.length === 0 ? '' : (toChars[Math.min(index, toChars.length - 1)] ?? ''); map.set(key, replacement); } let out = ''; for (const char of source) { out += map.has(char) ? (map.get(char) ?? char) : char; } return out; }