3

I am trying to solve a Javascript challenge on Codewars.

An isogram is a word that has no repeating letters, consecutive or non-consecutive. Implement a function that determines whether a string that contains only letters is an isogram. Assume the empty string is an isogram. Ignore letter case.

isIsogram( "Dermatoglyphics" ) == true
isIsogram( "aba" ) == false
isIsogram( "moOse" ) == false // -- ignore letter case

My effort is below:

    function isIsogram(str) {
    var arr = str.split("");
    var seen = {};
    var out = [];
    var length = arr.length;
    var j = 0;
    for(var i = 0; i < length; i++) {
         var item = arr[i].toLowerCase;
         if(seen[item] !== 1) {
               seen[item] = 1;
               out[j++] = item;
         }
    }
    console.log(out.toString.toLowerCase);
    console.log(str.toLowerCase);
    if (out.toString.toLowercase === str.toLowerCase) {
     return true;
    }
    else {
      return false;
    }
}

In codewars the result of my

console.log(out.toString.toLowerCase); is undefined 

and the result of

console.log(str.toLowerCase); is [Function: toLowerCase].

This means my solution always evaluates to false.

I would appreciate any help to point me in the right direction or highlight my errors instead of giving me the solution so I can learn more effectively. Thanks!

5 Answers 5

2

This may be a simpler answer.

function isIsogram(str){

  // Turn all letters of the string to lower case and split it into an array. 

  var letters = str.toLowerCase().split('');
  var checkLetters = [];
  
  /* Check to see if the letter appears in the checkLetters array.
     If the letter is not already in the array it will push the letter into it. */

  letters.forEach(function(letter) {
    if(checkLetters.indexOf(letter) === -1) {
      checkLetters.push(letter);
    }
  });

  /* Now we have two arrays. If the letters array has non-duplicate letters then 
     it will be the same length as the checkLetters array. If not, the checkLetters array
     will be shorter. */

  /* Return true or false depending on whether the lengths of both arrays are equal */
    
  return letters.length === checkLetters.length ? true : false;

}

Sign up to request clarification or add additional context in comments.

Comments

1

toString and toLowerCase are functions. In Javascript, to execute a function, you must add parenthesis on to the end of the function name:

out.toString().toLowerCase()
//          ^^            ^^

You need to do this for all your functions:

arr[i].toLowerCase()

str.toLowerCase

out.toString.toLowercase() === str.toLowerCase()

(Note that calling .toString() on an array will include commas, e.g. "a,b,c,d,e". Probably doesn't matter for this use case, but just to highlight that)

Comments

1

toString and toLowerCase etc are functions

use:

out.toString().toLowerCase()

however, for out, I think you want to do out.join('').toLowerCase()

Comments

0

I think that you can improve your solution, by doing in the functional way, using hashmap system, and every method.

The every method executes the provided callback function once for each element present in the array until it finds one where callback returns a falsy value

So, your code will be more clean.

  function isIsogram(str) {
    //Create our hashmap
    var hashmap = {};
    //Return value of 'every' loop
    return str.split("").every(function(elm){
      //If our hashmap get current letter as key
      return hashmap.hasOwnProperty(elm.toLowerCase())
      //Return false, str is not an Isogram
      ? false
      //Otherwise, set letter as key in our hashmap,
      //we can check the next iteration
      : hashmap[elm.toLowerCase()] = true;
    });
  }

console.log(isIsogram('Dermatoglyphics'));
console.log(isIsogram('moOse'));
console.log(isIsogram('aba'));

Comments

0

I know you've solved this, but just for variety. By ignoring case sensitivity, first change the input to lowercase.

function isIsogram(str) {
     // Change word to lower case
    str = str.toLowerCase();
      // split the word into letters and store as an array
    var arr = str.split("");
      // get the length so the array can be looped through
    var len = arr.length;
      // an array to contain letters that has been visited
    var seen = []
    for (var i = 0; i < len; i++) {
        // check if letter has not been visited by checking for the index
      if(seen.indexOf(arr[i])<0){
         // if the letter doesn't exist,add it to seen and go to next letter
        seen.push(arr[i]);
      }else{
         // if letter exists, the word is not an isogram return false
        return false
      }
    }
       // the loop is complete but each letter appeared once, the word is an isogram
   return true
}

console.log(isIsogram('Dermatoglyphics'));
console.log(isIsogram('moOse'));
console.log(isIsogram('aba'));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.