const words = [
"a",
"alien",
"born",
"less",
"lien",
"never",
"nevertheless",
"new",
"newborn",
"the",
"zebra",
"zebra",
];
let compoundArr = [];
let memo = new Map();
setFixes = () => {
for (let word of words) {
for (let i = 1; i < word.length; i++) {
const prefix = word.substring(0, i);
const suffix = word.substring(i);
if (memo.get(prefix)) return;
else {
if (words.includes(prefix)) memo.set(prefix, true);
}
if (memo.get(suffix)) return;
else {
if (words.includes(suffix)) memo.set(suffix, true);
}
}
}
};
findCompound = () => {
setFixes();
for (let word of words) {
for (let i = 1; i < word.length; i++) {
const prefix = word.substring(0, i);
const suffix = word.substring(i);
if (memo.get(prefix) === true && memo.get(suffix) === true) {
compoundArr.push(word);
}
}
}
return compoundArr;
};
findCompound();
console.log(compoundArr);
Hi, I am using a map here to store the prefixes and suffixes to avoid searching for same characters and bigger parts if possible. However I noticed that it never reads from the stored values, it skips this 'if (memo.get(prefix)) return
' and 'if (memo.get(suffix)) return
' part and moves to searching in the words array again. How can we solve this issue?
Here are some issues and remarks:
The function ends when a return
is executed, so as soon as a prefix/suffix is found to already be in the Map, the function stops any further processing. Instead of return
you'll want to just skip the part that writes to the Map for that particular string only.
As your code only ever uses and checks for the value true
in the Map, you can do with just a Set.
Your function variables are implicitly declared as globals. It is better practice to use const
to define them, or use the function
statement.
Use function parameters so that it is clear which variables might get used by them. And if the function creates a data structure, then have it return it (instead of mutating a global variable). Leave it to the caller to assign the function result to its own variables (which might then be global).
To avoid scanning the words
array repeatedly, it would be better to turn that array into a Set once, and then use has
instead of includes
.
As a compound word might consist of words that occur multiple times as prefixes and suffixes, you'll want the list of compound words to also be collected as a Set -- to avoid duplicates. You can turn it into an array as a final step.
const setFixes = (words) => {
const wordSet = new Set(words); // To speed up look-up
const fixes = new Set(); // Instead of Map
for (const word of words) {
for (let i = 1; i < word.length; i++) {
const prefix = word.substring(0, i);
const suffix = word.substring(i);
// Don't exit the function here -- just skip
if (wordSet.has(prefix)) fixes.add(prefix);
if (wordSet.has(suffix)) fixes.add(suffix);
}
}
return fixes; // Return it
};
const findCompound = (words) => {
const fixes = setFixes(words);
const compounds = new Set; // Local; and avoid duplicates
for (const word of words) {
for (let i = 1; i < word.length; i++) {
const prefix = word.substring(0, i);
const suffix = word.substring(i);
if (fixes.has(prefix) && fixes.has(suffix)) {
compounds.add(word);
}
}
}
return [...compounds]; // Turn to array
};
const words = ["a","alien","born","less","lien","never","nevertheless","new","newborn","the","zebra","zebra",];
const compoundArr = findCompound(words);
console.log(compoundArr);