Reputation: 3
trying to solve a task from codewars:
Write a function that will find all the anagrams of a word from a list. You will be given two inputs a word and an array with words. You should return an array of all the anagrams or an empty array if there are none.
anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) => ['aabb', 'bbaa']
Here's my solution:
function anagrams(str, arr) {
let newArr = [];
for(let i = 0; i < arr.length; i++) {
let result = str.split('').every(function(letter) {
return arr[i].indexOf(letter) != -1;
});
if(result === true) {
newArr.push(arr[i]);
}
}
return newArr;
}
Which is not working correctly: it displays ["aabb","abcd","bbaa"]
when ['aabb', 'bbaa']
is required.
Thank you in advance.
Upvotes: 0
Views: 806
Reputation: 351039
Although your function correctly checks that each letter of the word occurs in the potential anagram of it, it does not check that the number of duplicates of that letter is the same.
You could solve this by first determining the count of each distinct letter:
function getCounts(str) {
letterCount = {};
for (let letter of str) {
letterCount[letter] ??= 0;
letterCount[letter]++;
}
return letterCount;
}
function anagrams(str, arr) {
counts = getCounts(str);
return arr.filter(anagram =>
anagram.length === str.length &&
Object.entries(getCounts(anagram)).every(([letter, count]) =>
counts[letter] === count
)
);
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));
Upvotes: 0
Reputation: 101
I think you also need to manage the counts of letters. You get abcd
in your output because abba
is present in it according to this piece of code.
let result = str.split('').every(function(letter) {
return arr[i].indexOf(letter) != -1;
});
Upvotes: 0