Anagrams finder in javascript
Asked Answered
K

38

28

I am supposed to write a program in JavaScript to find all the anagrams within a series of words provided. e.g.:

monk, konm, nkom, bbc, cbb, dell, ledl, llde

The output should be categorised into rows:

1. monk konm, nkom;
2. bbc cbb;
3. dell ledl, llde;

I already sorted them into alphabetical order and put them into an array. i.e.:

kmno kmno bbc bbc dell dell

However I am stuck in comparing and finding the matching anagram within the array.

Any help will be greatly appreciated.

Kiddy answered 26/5, 2009 at 7:49 Comment(0)
A
22

Javascript objects are excellent for this purpose, since they are essentially key/value stores:

// Words to match
var words = ["dell", "ledl", "abc", "cba"];

// The output object
var anagrams = {};

for (var i in words) {
    var word = words[i];

    // sort the word like you've already described
    var sorted = sortWord(word);

    // If the key already exists, we just push
    // the new word on the the array
    if (anagrams[sorted] != null) {
        anagrams[sorted].push(word);
    } 
    // Otherwise we create an array with the word
    // and insert it into the object
    else {
        anagrams[sorted] = [ word ];
    }
}

// Output result
for (var sorted in anagrams) {
    var words = anagrams[sorted];
    var sep = ",";
    var out = "";
    for (var n in words) {
        out += sep + words[n];
        sep = "";
    }
    document.writeln(sorted + ": " + out + "<br />");
}
Athenaathenaeum answered 26/5, 2009 at 8:6 Comment(1)
Could you please elaborate your code? I am even more confused after reading this. Thanks in advance.Kiddy
J
22

Here is my take:

var input = "monk, konm, bbc, cbb, dell, ledl";
var words = input.split(", ");

for (var i = 0; i < words.length; i++) {

  var word = words[i];
  var alphabetical = word.split("").sort().join("");

  for (var j = 0; j < words.length; j++) {

    if (i === j) {
      continue;
    }

    var other = words[j];
    if (alphabetical === other.split("").sort().join("")) {
      console.log(word + " - " + other + " (" + i + ", " + j + ")");
    }
  }
}

where the output would be (the word, the match and the index of both):

monk - konm (0, 1)
konm - monk (1, 0)
bbc - cbb (2, 3)
cbb - bbc (3, 2)
dell - ledl (4, 5)
ledl - dell (5, 4)

To get the characters in the in alphabetical order, I used split("") ot get an array, called sort() and used join("") to get a string from the array.

Joacimah answered 26/5, 2009 at 8:20 Comment(0)
H
18

Simple Solution

function anagrams(stringA, stringB) {
    return cleanString(stringA) === cleanString(stringB);
}

function cleanString(str) {
    return str.replace(/[^\w]/g).toLowerCase().split('').sort().join()
}   

anagrams('monk','konm')

If it is anagrams function will return true otherwise false

Haarlem answered 15/7, 2018 at 6:21 Comment(2)
.join() without an argument will automatically join by commas, which probably isn't the best take. It's good practice to specify an empty string: .join("").Chair
Same for replace(), you should provide a replacement, in this case an empty string. Otherwise it will replace matches with undefined.Bombe
B
9

I worked through a similar question to this today and wanted to share the results of my work. I was focused on just detecting the anagram so processing the list of words was not part of my exercise but this algorithm should provide a highly performant way to detect an anagram between two words.

function anagram(s1, s2){
  if (s1.length !== s2.length) {
    // not the same length, can't be anagram
    return false;
  }
  if (s1 === s2) {
    // same string must be anagram
    return true;
  }

  var c = '',
    i = 0,
    limit = s1.length,
    match = 0,
    idx;
  while(i < s1.length){
    // chomp the next character
    c = s1.substr(i++, 1);
    // find it in the second string
    idx = s2.indexOf(c);
    if (idx > -1) {
      // found it, add to the match
      match++;
      // assign the second string to remove the character we just matched
      s2 = s2.substr(0, idx) + s2.substr(idx + 1);
    } else {
      // not found, not the same
      return false;
    }
  }
  return match === s1.length;
}

I think technically is can be solved like this:

function anagram(s1, s2){
  return s1.split("").sort().join("") === s2.split("").sort().join("");
}

The reason I chose the earlier approach is that it is more performant for larger strings since you don't need to sort either string, convert to an array or loop through the entire string if any possible failure case is detected.

Basilius answered 16/5, 2013 at 0:50 Comment(0)
C
9

Probably not the most efficient way, but a clear way around using es6

function sortStrChars(str) {
  if (!str) {
    return;
  }
  str = str.split('');
  str = str.sort();
  str = str.join('');
  return str;
}

const words = ["dell", "ledl", "abc", "cba", 'boo'];

function getGroupedAnagrams(words) {
  const anagrams = {}; // {abc:[abc,cba], dell:[dell, ledl]}
  words.forEach((word) => {
    const sortedWord = sortStrChars(word);
    if (anagrams[sortedWord]) {
      return anagrams[sortedWord].push(word);
    }
    anagrams[sortedWord] = [word];
  });
  return anagrams;
}

const groupedAnagrams = getGroupedAnagrams(words);
for (const sortedWord in groupedAnagrams) {
  console.log(groupedAnagrams[sortedWord].toString());
}
Chow answered 5/7, 2016 at 12:10 Comment(0)
N
4

I had this question in an interview. Given an array of words ['cat', 'dog', 'tac', 'god', 'act'], return an array with all the anagrams grouped together. Makes sure the anagrams are unique.

var arr = ['cat', 'dog', 'tac', 'god', 'act'];

var allAnagrams = function(arr) {
    var anagrams = {};
    arr.forEach(function(str) {
        var recurse = function(ana, str) {
            if (str === '') 
                anagrams[ana] = 1;
            for (var i = 0; i < str.length; i++)
                recurse(ana + str[i], str.slice(0, i) + str.slice(i + 1));
        };
        recurse('', str);
    });
    return Object.keys(anagrams);
}

console.log(allAnagrams(arr));
//["cat", "cta", "act", "atc", "tca", "tac", "dog", "dgo", "odg", "ogd", "gdo", "god"]
Nieshanieto answered 10/2, 2015 at 20:57 Comment(0)
P
4

Best and simple way to solve is using for loops and traversing it to each string and then store their result in object.

Here is the solution :-

function anagram(str1, str2) {
    if (str1.length !== str2.length) {
        return false;
    }
    const result = {};
    for (let i=0;i<str1.length;i++) {
        let char = str1[i];
        result[char] = result[char] ? result[char] += 1 : result[char] = 1;
    }

    for (let i=0;i<str2.length;i++) {
        let char = str2[i];
        if (!result[char]) {
            return false;
        }
        else {
            result[char] = -1;
        }
    }
    return true;
}

console.log(anagram('ronak','konar'));
Psychasthenia answered 18/12, 2019 at 14:21 Comment(4)
Great solution! This is faster than solutions based on sorting. This is of time complexity O(n), compared to sorting that should be at best O(n logn), if I'm not mistaken. :) They might be easier to read though...Agreeable
Thanks @AgreeablePsychasthenia
This is cleaner than the second solution. It uses a frequency pattern by creating a object to keep track of the characters and uses non nested loops that maintain O(n) time.Mother
this line is not necessary I guess: result[char] = -1;Mihalco
T
3

I know this is an ancient post...but I just recently got nailed during an interview on this one. So, here is my 'new & improved' answer:

var AnagramStringMiningExample = function () {

/* Author: Dennis Baughn
*  This has also been posted at: 
*  https://mcmap.net/q/486218/-anagrams-finder-in-javascript/5642437#5642437

*  Free, private members of the closure and anonymous, innner function
*  We will be building a hashtable for anagrams found, with the key 
*  being the alphabetical char sort (see sortCharArray()) 
*  that the anagrams all have in common. 
*/
    var dHash = {};

    var sortCharArray = function(word) {
        return word.split("").sort().join("");
    };

/* End free, private members for the closure and anonymous, innner function */

/* This goes through the dictionary entries. 
 *  finds the anagrams (if any) for each word,
 *  and then populates them in the hashtable. 
 *  Everything strictly local gets de-allocated 
 *  so as not to pollute the closure with 'junk DNA'.
*/
    (function() {
       /* 'dictionary' referring to English dictionary entries. For a real 
        *  English language dictionary, we could be looking at 20,000+ words, so 
        *  an array instead of a string would be needed.
        */
       var dictionaryEntries = "buddy,pan,nap,toot,toto,anestri,asterin,eranist,nastier,ratines,resiant,restain,retains,retinas,retsina,sainter,stainer,starnie,stearin";
       /* This could probably be refactored better.  
        * It creates the actual hashtable entries. */
       var populateDictionaryHash = function(keyword, newWord) {
          var anagrams = dHash[keyword];
          if (anagrams && anagrams.indexOf(newWord) < 0) 
            dHash[keyword] = (anagrams+','+newWord);
          else dHash[keyword] = newWord;
       };

       var words = dictionaryEntries.split(",");

       /* Old School answer, brute force
       for (var i = words.length - 1; i >= 0; i--) {
        var firstWord = words[i];
        var sortedFirst = sortCharArray(firstWord);
        for (var k = words.length - 1; k >= 0; k--) {
               var secondWord = words[k];
           if (i === k) continue;
            var sortedSecond = sortCharArray(secondWord);
            if (sortedFirst === sortedSecond)   
                       populateDictionaryHash(sortedFirst, secondWord);
        }
       }/*

        /*Better Method for JS, using JS Array.reduce(callback) with scope binding on callback function */
        words.reduce(function (prev, cur, index, array) { 
            var sortedFirst = this.sortCharArray(prev);
            var sortedSecond = this.sortCharArray(cur); 
            if (sortedFirst === sortedSecond) {
                var anagrams = this.dHash[sortedFirst];
                if (anagrams && anagrams.indexOf(cur) < 0) 
                   this.dHash[sortedFirst] = (anagrams + ',' + cur);
                else 
                   this.dHash[sortedFirst] = prev + ','+ cur;                    
            }
            return cur;
        }.bind(this));
    }());

    /* return in a nice, tightly-scoped closure the actual function 
     *  to search for any anagrams for searchword provided in args and render results. 
    */
    return function(searchWord) {
       var keyToSearch = sortCharArray(searchWord);
       document.writeln('<p>');
       if (dHash.hasOwnProperty(keyToSearch)) {
        var anagrams = dHash[keyToSearch];
        document.writeln(searchWord + ' is part of a collection of '+anagrams.split(',').length+' anagrams: ' + anagrams+'.');
       } else document.writeln(searchWord + ' does not have anagrams.');
       document.writeln('<\/p>');
    };
};

Here is how it executes:

var checkForAnagrams = new AnagramStringMiningExample();
checkForAnagrams('toot');
checkForAnagrams('pan');
checkForAnagrams('retinas');
checkForAnagrams('buddy');

Here is the output of the above:

toot is part of a collection of 2 anagrams: toto,toot.

pan is part of a collection of 2 anagrams: nap,pan.

retinas is part of a collection of 14 anagrams: stearin,anestri,asterin,eranist,nastier,ratines,resiant,restain,retains,retinas,retsina,sainter,stainer,starnie.

buddy does not have anagrams.

Telecommunication answered 12/4, 2011 at 22:36 Comment(0)
E
2

My solution to this old post:

// Words to match
var words = ["dell", "ledl", "abc", "cba"],
    map = {};

//Normalize all the words 
var normalizedWords = words.map( function( word ){
  return word.split('').sort().join('');
});

//Create a map: normalizedWord -> real word(s)
normalizedWords.forEach( function ( normalizedWord, index){
  map[normalizedWord] = map[normalizedWord] || [];
  map[normalizedWord].push( words[index] );
});

//All entries in the map with an array with size > 1 are anagrams
Object.keys( map ).forEach( function( normalizedWord , index  ){
  var combinations = map[normalizedWord];
  if( combinations.length > 1 ){
    console.log( index + ". " + combinations.join(' ') );
  }
});

Basically I normalize every word by sorting its characters so stackoverflow would be acefkloorstvw, build a map between normalized words and the original words, determine which normalized word has more than 1 word attached to it -> That's an anagram.

Equilateral answered 16/7, 2014 at 13:43 Comment(1)
Sure, text normalization is the process of transforming text into a single canonical form. The canonical form here is the text with its characters sorted.Equilateral
J
2

Maybe this?

function anagram (array) {
    var organized = {};
    for (var i = 0; i < array.length; i++) {
        var word = array[i].split('').sort().join('');
        if (!organized.hasOwnProperty(word)) {
            organized[word] = [];
        }
        organized[word].push(array[i]);
    }    
    return organized;
}


anagram(['kmno', 'okmn', 'omkn', 'dell', 'ledl', 'ok', 'ko']) // Example

It'd return something like

{
    dell: ['dell', 'ledl'],
    kmno: ['kmno', okmn', 'omkn'],
    ko: ['ok', ko']
}

It's a simple version of what you wanted and certainly it could be improved avoiding duplicates for example.

Joacima answered 28/12, 2016 at 18:30 Comment(0)
R
2

My two cents.

This approach uses XOR on each character in both words. If the result is 0, then you have an anagram. This solution assumes case sensitivity.

let first = ['Sower', 'dad', 'drown', 'elbow']
let second = ['Swore', 'add', 'down', 'below']

// XOR all characters in both words
function isAnagram(first, second) {
  // Word lengths must be equal for anagram to exist
  if (first.length !== second.length) {
    return false
  }

  let a = first.charCodeAt(0) ^ second.charCodeAt(0)

  for (let i = 1; i < first.length; i++) {
    a ^= first.charCodeAt(i) ^ second.charCodeAt(i)
  }

  // If a is 0 then both words have exact matching characters
  return a ? false : true
}

// Check each pair of words for anagram match
for (let i = 0; i < first.length; i++) {
  if (isAnagram(first[i], second[i])) {
    console.log(`'${first[i]}' and '${second[i]}' are anagrams`)
  } else {
    console.log(`'${first[i]}' and '${second[i]}' are NOT anagrams`)
  }
}
Rijeka answered 14/3, 2020 at 16:33 Comment(0)
S
1
function isAnagram(str1, str2) {
  var str1 = str1.toLowerCase();
  var str2 = str2.toLowerCase();

  if (str1 === str2)
    return true;

  var dict = {};

  for(var i = 0; i < str1.length; i++) {
    if (dict[str1[i]])
      dict[str1[i]] = dict[str1[i]] + 1;
    else
      dict[str1[i]] = 1;
  }

  for(var j = 0; j < str2.length; j++) {
    if (dict[str2[j]])
      dict[str2[j]] = dict[str2[j]] - 1;
    else
      dict[str2[j]] = 1;
  }

  for (var key in dict) {
    if (dict[key] !== 0) 
      return false;
  }

  return true;
}

console.log(isAnagram("hello", "olleh"));
Sassanid answered 1/6, 2016 at 16:50 Comment(0)
C
1

I have an easy example

function isAnagram(strFirst, strSecond) {

 if(strFirst.length != strSecond.length)
       return false;

 var tempString1 = strFirst.toLowerCase();
 var tempString2 = strSecond.toLowerCase();

 var matched = true ;
 var cnt = 0;
 while(tempString1.length){
    if(tempString2.length < 1)
        break;
    if(tempString2.indexOf(tempString1[cnt]) > -1 )
        tempString2 = tempString2.replace(tempString1[cnt],'');
    else
        return false;

    cnt++;
 }

 return matched ;

 }

Calling function will be isAnagram("Army",Mary); Function will return true or false

Carbo answered 8/12, 2016 at 11:52 Comment(1)
Works great! Can you explain the logic a bit.Hypoglycemia
P
1
  1. Compare string length, if not equal, return false
  2. Create character Hashmap which stores count of character in strA e.g. Hello --> {H: 1, e: 1, l: 2, o: 1}
  3. Loop over the second string and lookup the current character in Hashmap. If not exist, return false, else decrement the value by 1
  4. If none of the above return falsy, it must be an anagram

Time complexity: O(n)

function isAnagram(strA: string, strB: string): boolean {
  const strALength = strA.length;
  const strBLength = strB.length;
  const charMap = new Map<string, number>();

  if (strALength !== strBLength) {
    return false;
  }

  for (let i = 0; i < strALength; i += 1) {
    const current = strA[i];

    charMap.set(current, (charMap.get(current) || 0) + 1);
  }

  for (let i = 0; i < strBLength; i += 1) {
    const current = strB[i];

    if (!charMap.get(current)) {
      return false;
    }

    charMap.set(current, charMap.get(current) - 1);
  }

  return true;
}
Promisee answered 31/3, 2020 at 6:52 Comment(4)
Shouldn't charMap.set(current, -1); be charMap.set(current,charMap.get(current) - 1);?Redheaded
@JustinThomas good point but actually it is not needed. The reason for that is that the conditions checks if both strings have the same length. Still thanks for pointing that out!Promisee
What if you have: catt and caat?Redheaded
You are right. I will adjust my code. Thanks for pointing out! +1Promisee
T
1
    let words = ["dell", "ledl","del", "abc", "cba", 'boo'];
    
    //sort each item 
    function sortArray(data){
      var r=data.split('').sort().join().replace(/,/g,'');
      return r;
    }
    
    var groupObject={};
    words.forEach((item)=>{
    let sorteditem=sortArray(item);
    
//Check current item is in the groupObject or not.
    //If not then add it as an array
    //else push it to the object property
    if(groupObject[sorteditem])
      return groupObject[sorteditem].push(item);
    groupObject[sorteditem]=[sorteditem];
    });
    
    //to print the result
    for(i=0;i<Object.keys(groupObject).length;i++)
       document.write(groupObject[Object.keys(groupObject)[i]] + "<br>");
    
    /* groupObject value: 
    abc: (2) ["abc", "cba"]
    boo: ["boo"]
    del: ["del"]
    dell: (2) ["dell", "ledl"]
    
    OUTPUT:
    ------
    dell,ledl
    del
    abc,cba
    boo
    */
Thetis answered 26/6, 2020 at 12:4 Comment(0)
S
1
function findAnagram(str1, str2) {

  let mappedstr1 = {}, mappedstr2 = {};

  for (let item of str1) {
    mappedstr1[item] = (mappedstr1[item] || 0) + 1;
  }

  for (let item2 of str2) {
    mappedstr2[item2] = (mappedstr2[item2] || 0) + 1;
  }

  for (let key in mappedstr1) {
    if (!mappedstr2[key]) {
      return false;
    }

    if (mappedstr1[key] !== mappedstr2[key]) {
      return false;
    }
  }

  return true;
}
console.log(findAnagram("hello", "hlleo"));
Statesman answered 3/2, 2021 at 13:24 Comment(0)
G
1

Another example only for comparing 2 strings for an anagram.

   function anagram(str1, str2) {
      if (str1.length !== str2.length) {
        return false;
      } else {
        if (
          str1.toLowerCase().split("").sort().join("") ===
          str2.toLowerCase().split("").sort().join("")
        ) {
          return "Anagram";
        } else {
          return "Not Anagram";
        }
      }
    }
    
    console.log(anagram("hello", "olleh"));
    console.log(anagram("ronak", "konar"));
Godspeed answered 19/2, 2021 at 10:36 Comment(1)
Please add an explanation to what this code does and howDefray
C
1
function anagram(string1, string2) {
    if (string1.toLowerCase() === string2.toLowerCase()) {
       return 'anagram'
    } else if (string1.length === string2.length) {

    if (string1.toLowerCase().split("").sort().join() === string2.toLowerCase().split("").sort().join()) {
      return 'anagram'
    }
  } else { return 'not a anagram' }
}



console.log(anagram('listen','silent'))
Celina answered 4/7, 2022 at 12:25 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Counterwork
D
1
const str1 ="1123451"
const str2 = "2341151"

function anagram(str1,str2) {
    let count = 0;
    if (str1.length!==str2.length) { return false;}
    for(i1=0;i1<str1.length; i1++) {
        for (i2=0;i2<str2.length; i2++) {
            if (str1[i1]===str2[i2]){
                count++;
                break;
            }
        } 
    }
    if (count===str1.length) { return true}
}
anagram(str1,str2)
Debauchee answered 13/11, 2022 at 6:37 Comment(0)
S
0

Another solution for isAnagram using reduce

const checkAnagram = (orig, test) => {
  return orig.length === test.length 
    && orig.split('').reduce(
      (acc, item) => {
        let index = acc.indexOf(item);
        if (index >= 0) {
          acc.splice(index, 1);
          return acc;
        }
        throw new Error('Not an anagram');
      },
      test.split('')
    ).length === 0;
};

const isAnagram = (tester, orig, test) => {
  try {
    return tester(orig, test);  
  } catch (e) {
    return false;
  }
}

console.log(isAnagram(checkAnagram, '867443', '473846'));
console.log(isAnagram(checkAnagram, '867443', '473846'));
console.log(isAnagram(checkAnagram, '867443', '475846'));
Sirotek answered 16/9, 2017 at 7:17 Comment(0)
D
0
var check=true;
var str="cleartrip";
var str1="tripclear";
if(str.length!=str1.length){
console.log("Not an anagram");

check=false;
}
console.log(str.split("").sort());
console.log("----------"+str.split("").sort().join(''));
if(check){
if((str.split("").sort().join(''))===((str1.split("").sort().join('')))){
console.log("Anagram")
}
else{
console.log("not a anagram");
}
}
Detached answered 11/3, 2018 at 12:26 Comment(1)
Its case sensitiveDetached
M
0

Here is my solution which addresses a test case where the input strings which are not anagrams, can be removed from the output. Hence the output contains only the anagram strings. Hope this is helpful.

/**
 * Anagram Finder
 * @params {array} wordArray
 * @return {object}
 */
function filterAnagram(wordArray) {
  let outHash = {};
  for ([index, word] of wordArray.entries()) {
    let w = word.split("").sort().join("");
    outHash[w] = !outHash[w] ? [word] : outHash[w].concat(word);
  }
  let filteredObject = Object.keys(outHash).reduce(function(r, e) {
    if (Object.values(outHash).filter(v => v.length > 1).includes(outHash[e])) r[e] = outHash[e]
    return r;
  }, {});

  return filteredObject;
}

console.log(filterAnagram(['monk', 'yzx','konm', 'aaa', 'ledl', 'bbc', 'cbb', 'dell', 'onkm']));
Morality answered 19/1, 2019 at 19:54 Comment(0)
D
0

i have recently faced this in the coding interview, here is my solution.

    function group_anagrams(arr) {
      let   sortedArr = arr.map(item => item.split('').sort().join(''));
      let setArr = new Set(sortedArr);
      let reducedObj = {};
      for (let setItem of setArr) {
        let indexArr = sortedArr.reduce((acc, cur, index) => {
          if (setItem === cur) {
            acc.push(index);
          }
          return acc;
        }, []);
        reducedObj[setItem] = indexArr;
      }
      let finalArr = [];
      for (let reduceItem in reducedObj) {
        finalArr.push(reducedObj[reduceItem].map(item => arr[item]));
      }
      return finalArr;
    }
    group_anagrams(['car','cra','rca', 'cheese','ab','ba']);

output will be like

[
  ["car", "cra", "rca"],
  ["cheese"],
  ["ab", "ba"]
]
Dehart answered 3/4, 2019 at 4:45 Comment(0)
O
0

My solution has more code, but it avoids using .sort(), so I think this solution has less time complexity. Instead it makes a hash out of every word and compares the hashes:

const wordToHash = word => {
  const hash = {};
  // Make all lower case and remove spaces
  [...word.toLowerCase().replace(/ /g, '')].forEach(letter => hash[letter] ? hash[letter] += 1 : hash[letter] = 1);
  return hash;
}
const hashesEqual = (obj1, obj2) => {
  const keys1 = Object.keys(obj1), keys2 = Object.keys(obj2);
  let match = true;
  if(keys1.length !== keys2.length) return false;
  for(const key in keys1) { if(obj1[key] !== obj2[key]) match = false; break; }
  return match;
}
const checkAnagrams = (word1, word2) => {
  const hash1 = wordToHash(word1), hash2 = wordToHash(word2);
  return hashesEqual(hash1, hash2);
}
console.log( checkAnagrams("Dormitory", "Dirty room") );
Ormond answered 1/5, 2020 at 3:45 Comment(0)
T
0
/*This is good option since 
  logic is easy,
  deals with duplicate data,
  Code to check anagram in an array,
  shows results in appropriate manner,
  function check can be separately used for comparing string in this regards with all benefits mentioned above.
  */

var words = ["deuoll", "ellduo", "abc","dcr","frt", "bu","cba","aadl","bca","elduo","bac","acb","ub","eldou","ellduo","ert","tre"];
var counter=1;
var ele=[];
function check(str1,str2)
{   
    if(str2=="")
    return false;
    if(str1.length!=str2.length)
      return false;
    var r1=[...(new Set (str1.split('').sort()))]; 
    var r2=[...(new Set (str2.split('').sort()))]; 
    var flag=true;

    r1.forEach((item,index)=>
    {
    if(r2.indexOf(item)!=index)
    { flag=false;}
    });

    return flag;
}

var anagram=function ()
{
  for(var i=0;i<words.length && counter!=words.length ;i++)
  {
  if(words[i]!="")
  {
    document.write("<br>"+words[i]+":");
    counter++;
    }
    for(var j=i+1;j<words.length && counter !=words.length+1;j++)
    {
       if(check(words[i],words[j]))
       {
              ele=words[j];
             document.write(words[j]+"&nbsp");
             words[j]="";
              counter++;   
       }
     }
  }
}
anagram();
Thetis answered 22/6, 2020 at 3:56 Comment(0)
P
0

If you just need count of anagrams

const removeDuplicatesAndSort = [...new Set(yourString.split(', '))].map(word => word.split('').sort().join())
const numberOfAnagrams = removeDuplicatesAndSort.length  - [...new Set(removeDuplicatesAndSort)].length
Pga answered 27/6, 2020 at 11:3 Comment(0)
P
0
function isAnagram(str1, str2){
  let count = 0;

  if (str1.length !== str2.length) {
    return false;
  } else {
    let val1 = str1.toLowerCase().split("").sort();
    let val2 = str2.toLowerCase().split("").sort();
    for (let i = 0; i < val2.length; i++) {
      if (val1[i] === val2[i]) {
        count++;
      }
    }
  if (count == str1.length) {
    return true;
   }
 }
 return false;
}

console.log(isAnagram("cristian", "Cristina"))
Ponzo answered 26/8, 2020 at 15:15 Comment(0)
G
0
function findAnagrams (str, arr){
let newStr = "";
let output = [];

for (let i = 0; i < arr.length; i++) {
  for (let j = 0; j < arr[i].length; j++) {
    for (let k = 0; k < str.length; k++) {
      if (str[k] === arr[i][j] && str.length === arr[i].length) {
        newStr += arr[i][j];
      }
    }
  } if(newStr.length === str.length){
    output.push(newStr);
    newStr = "";
  }
  }
  return output;
}
Gravitative answered 5/1, 2021 at 12:49 Comment(2)
Welcome to StackOverflow. While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.Lucrece
high complexity.Deform
M
0
const getAnagrams = (...args) => {
    const anagrams = {};

    args.forEach((arg) => {        
        const letters = arg.split("").sort().join("");

        if (anagrams[letters]) {
            anagrams[letters].push(arg);
        } else {
            anagrams[letters] = [arg];
        }
    });
    
    return Object.values(anagrams);
}
Maynard answered 21/2, 2021 at 17:16 Comment(2)
Please explain what your code does. An explanation will help both current and future visitors understand your code.Lycanthrope
Hi @FriendlyBanana, it solves the problem from the question. There is nothing to explain.Maynard
T
0

 function isAnagaram(str1, str2){
        if(str1.length!== str2.length){
            return false;
        }
        var obj1 = {};
        var obj2 = {};
        for(var arg of str1){
            obj1[arg] =  (obj1[arg] || 0 ) + 1 ;
        }
        for(var arg of str2){
            obj2[arg] =  (obj2[arg] || 0 ) + 1 ;
        }
    
        for( var key in obj1){
            if(obj1[key] !== obj2[key]){
                return false;
            }
        }
        return true;
    }
    
    console.log(isAnagaram('texttwisttime' , 'timetwisttext'));
Truth answered 22/2, 2021 at 16:52 Comment(0)
T
0
let validAnagram = (firstString, secondString) => {
    if (firstString.length !== secondString.length) {
        return false;
    }

    let secondStringArr = secondString.split('');

    for (var char of firstString) {
        charIndexInSecondString = secondString.indexOf(char);
        if (charIndexInSecondString === -1) {
            return false;
        }
        secondString = secondString.replace(char, '');
    }

    
    return true;
}
Tecu answered 18/7, 2021 at 20:28 Comment(0)
A
0
const arr = ['monk', 'konm', 'nkom', 'bbc', 'cbb', 'dell', 'ledl', 'llde'];
let anagram = {};

for (let i = 0; i<arr.length; i++){
  const word = arr[i];
  const sortedWord = word.split("").sort().join("");
  let tempArray = [];
  if(anagram[sortedWord]){
    tempArray = anagram[sortedWord].length==1?anagram[sortedWord]:[...anagram[sortedWord]];
    tempArray.push(word);
    anagram[sortedWord] = tempArray;
  }else{
    anagram[sortedWord] = [word];
  }
}
console.log(Object.values(anagram));
Aphesis answered 23/8, 2021 at 7:53 Comment(0)
S
0

the answer that comes to my mind:

function anagrams(stringA, stringB) {
  const aCharMap = buildCharMap(stringA);
  const bCharMap = buildCharMap(stringB);

  if (Object.keys(aCharMap).length !== Object.keys(bCharMap).length) {
    return false;
  }

  for (let char in aCharMap) {
    if (aCharMap[char] !== bCharMap[char]) {
      return false;
    }
  }

  return true;
}

helper function:

function buildCharMap(str) {
  const charMap = {};

  for (let char of str.replace(/[^\w]/g, '')) {
    charMap[char] = charMap[char] + 1 || 1;
  }

  return charMap;
}

but if you're looking for the easiest way:

function anagrams(stringA, stringB) {
  return cleanString(stringA) === cleanString(stringB);
}


function cleanString(str) {
  return str.replace(/[^\w]/g, '').toLowerCase().split('').sort().join('');
}
Spate answered 18/12, 2021 at 16:59 Comment(0)
S
0

Here, I would first convert list of words in to anagram object. I am pushing anagram words in to new object where key is anagram. if anagram is already found in the object then I would concat the new word.

At last I am just taking out the values of result object. Code is self explanatory and short.

const input = "monk, konm, nkom, bbc, cbb, dell, ledl, llde";

const anagramCreater = (data) => { return data.split("").sort().join("");}

const anagram = input
.split(", ")
.reduce((acc, word) => {
  const anagramWord = anagramCreater(word);
  acc[anagramWord] = acc[anagramWord] 
    ? `${acc[anagramWord]},${word}` 
    : word;
  return acc;
}, {});
console.log(Object.values(anagram).join("\n"));
Stomacher answered 7/2, 2022 at 8:41 Comment(0)
P
0

function isAnagram(item1, item2) {
    if (!item1 || !item2 || item1 == item2 || item1.length != item2.length) return false
    const ret = item1.split("").reduce((acc, c) => {
        const index = acc.indexOf(c);
        if (index > -1) acc.splice(index, 1)
        return acc
    }, item2.split(""))
    return ret.length == 0
}

console.log( isAnagram("pippo", "opppi") )
Prophase answered 17/10, 2022 at 10:7 Comment(0)
F
0

If you order the letters for the words you can compare them easily:

const list = ['monk', 'konm', 'nkom', 'bbc', 'cbb', 'dell', 'ledl', 'llde'];

// creates a map for each anagram list
const anagramsMap = list.reduce((acc, curr, index) => {
    const sortedWord = curr.split('').sort().join('');
    return {...acc, [sortedWord]: [curr, ...acc[sortedWord ] || []]};
}, {});

// outputs one anagrams list per line
Object.values(anagramsMap ).forEach(items => console.log(items.join(', ')));
Forceps answered 1/8, 2023 at 11:10 Comment(0)
N
0

3 line of code is enough for this. Please have a look.

const arr = ["monk", "konm", "nkom", "bbc", "cbb", "dell", "ledl", "llde"];

let a = {};
arr.forEach((word,index) => {
    const sortedText = word.split("").sort().join("");
    a[sortedText]=[...(a[sortedText]||[]),arr[index]]
});

console.log([Object.values(a)])
Nicholson answered 28/3 at 12:16 Comment(0)
K
-1
function checkAnagram(str1, str2) {
    str1 = str1.toLowerCase();
    str2 = str2.toLowerCase();
    let sum1 = 0;
    let sum2 = 0;
    for (let i = 0; i < str1.length; i++) {
        sum1 = sum1 + str1.charCodeAt(i);
    }
    for (let j = 0; j < str2.length; j++) {
        sum2 = sum2 + str2.charCodeAt(j);
    }
    if (sum1 === sum2) {
        return "Anagram";
    } else {
        return "Not Anagram";
    }
}
Kisung answered 7/2, 2020 at 6:56 Comment(1)
please consider adding a comment explaining how your answer solves the OP's problemWeatherboard

© 2022 - 2024 — McMap. All rights reserved.