DEV Community

James Robb
James Robb

Posted on • Updated on

Where my anagrams at?

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");
  });
});
Enter fullscreen mode Exit fullscreen mode

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));
}
Enter fullscreen mode Exit fullscreen mode

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)