Was thinking, the most concise version of this just exploits the ascii table to eliminate most of the checks. And also probably fails code review:
reduce(([previous, result], val: string) =>
previous !== result &&
(Math.abs(previous.charCodeAt(0) - val.charCodeAt(0))) === 0x20
? [result.charAt(result.length - 2), result.slice(0, result.length - 1)]
: [val, result + val]
, ['', '']),
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.