Task description
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.
Task solution
Tests
describe("anagram tests", () => {
it("Should throw for invalid input", () => {
expect(() => anagrams(1)).toThrow(/IllegalArgumentException/);
expect(() => anagrams("test", 1)).toThrow(/IllegalArgumentException/);
expect(() => anagrams("test", [1])).toThrow(/IllegalArgumentException/);
expect(() => anagrams("test", ["test"], 1)).toThrow(/IllegalArgumentException/);
});
it("Should find all anagrams", () => {
expect(anagrams("abba", ["aabb", "abcd", "bbaa", "dada"])).toEqual(["aabb", "bbaa"]);
expect(anagrams("racer", ["crazer", "carer", "racar", "caers", "racer"])).toEqual(["carer", "racer"]);
expect(anagrams("laser", ["lazing", "lazy", "lacer"])).toEqual([]);
function customSort(string) {
return string.toLowerCase().split("").sort().reverse().join("");
}
expect(anagrams("Listen", ["Silent"], customSort)).toEqual(["Silent"]);
});
});
describe("sortString tests", () => {
it("Should return the input if not a string", () => {
expect(sortString(1)).toBe(1);
});
it("Should return a sorted string as expected with valid input provided", () => {
expect(sortString("acb")).toBe("abc");
});
});
We begin with out invalid input tests, you will note that there is a 3rd parameter that users can add into the function outside of just the word
to find and the words
we wish the check if that word
is an anagram of. This is because I am also allowing a custom sorting function to be applied if the user wishes. This is useful for if they rely on a third party framework and wish to use that implementation for example. Either way we test this out too to be sure it works as expected as we should do with all our code to the best of our abilities.
Implementation
function sortString(string) {
if(typeof string !== "string") return string;
return string.toLowerCase().split("").sort().join("");
}
function anagrams(word, words, sortingFunc = sortString) {
if(typeof word !== "string") {
throw new Error(`IllegalArgumentException: Parameter 1 must be a string. Received: ${typeof word}`);
} else if(!Array.isArray(words)) {
throw new Error(`IllegalArgumentException: Parameter 2 must be an array. Received: ${typeof words}`);
} else if(!words.every(word => typeof word === "string")) {
throw new Error(`IllegalArgumentException: Parameter 2 must be an array of strings but atlease one value within the array is not a string. Received: ${words}`);
} else if(typeof sortingFunc !== "function") {
throw new Error(`IllegalArgumentException: Parameter 3 must be a function. Received: ${typeof sortingFunc}`);
}
return words.filter(w => sortingFunc(w) === sortingFunc(word));
}
We write a helper function called sortString
, this is to normalise each item into a string we can compare against the normalised word
we are comparing it to, this helper will be the default implementation for parameter 3. Next we run our normal input validation tests and follow that with a simple filter
call on the words array.
When filtering the words
array, we want to return only the items which are anagrams of the word
we are provided. In this way, we run the sortingFunc
which, if no alternative is provided, will be our sortString
function, over our current word (w
) in the loop and our word
we are searching for. If both match, we know it must be an anagram and thus it will be returned in the filtered output.
Conclusions
This task was really easy but it is still something that's good for a quick brush up from time to time, for example: default parameter usage, working with data, etc. Foundational things and yet sometimes forgotten, either way, a simple solution to a simple problem was found. See you in the next one!
Top comments (0)