function groupByFirstNLetters(s: string, n: number = 3): Record<string, string[]> {
return (s.toLowerCase().match(/[a-zA-Z]+/g) ?? [])
.filter(w => w.length >= n)
.reduce<Record<string, string[]>>((groups, w) => {
const prefix = w.slice(0, n);
(groups[prefix] ??= []).push(w);
return groups;
}, {});
}
const s =
"The lowly inhabitants of the lowland were surprised to see the lower branches of the trees.";
const groups = groupByFirstNLetters(s, 3);
// Print version 1
for (const [prefix, words] of Object.entries(groups)) {
console.log(prefix, ":", words);
}
console.log();
// Print version 2
for (const [prefix, words] of Object.entries(groups)) {
console.log(`${prefix}: ${words.join(", ")}`);
}
/*
run:
"the", ":", ["the", "the", "the", "the"]
"low", ":", ["lowly", "lowland", "lower"]
"inh", ":", ["inhabitants"]
"wer", ":", ["were"]
"sur", ":", ["surprised"]
"see", ":", ["see"]
"bra", ":", ["branches"]
"tre", ":", ["trees"]
"the: the, the, the, the"
"low: lowly, lowland, lower"
"inh: inhabitants"
"wer: were"
"sur: surprised"
"see: see"
"bra: branches"
"tre: trees"
*/