Search code examples
javascriptarraysuppercaselowercase

array.includes method not counting uppercase letters


I wrote a program that is supposed to verify if a random string is a pangram(contain all the letters of the alphabet), I transformed the string that is the parameter of the function into an array, then I checked letter by letter and putted every new letter found into a new array and added 1 to the counter. If the counter is equal to 26 the function returns true, else, it returns false. But it seems that the Array.includes method used is not counting uppercase letters, for some reason, i thought it would count the same letter twice is it appears in lowercase and uppercase. somebody can help me with this? My code is below:

function pangram (string){
  let alphabet =
    ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
  let arrayString = Array.from(string);
  let counterArray = [];
  let counter = 0;
  
  for(let i = 0; i <= arrayString.length-1; i++){
    for(let j = 0; j <= alphabet.length-1; j++){
      if(arrayString[i] === alphabet[j]){
          if(counterArray.includes(arrayString[i])){
              counter;
          } else {
              counterArray.push(arrayString[i]);
              counter++;
          }
      }
    }
  }
  
  if(counter ===  26){
    return true;
  } else {
    return counter;
  }
}

Solution

  • You can do it before turning the string into an array

    const arrayString = [...string.toLowerCase()];
    

    I would also suggest you my solution for the whole problem. I hope it would be helpful to you.

    function pangram(string) {
      const alphabet =
        ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
          'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
      const newStr = [
              ...new Set(
                string.toLowerCase()
                .split('')
                .filter(l => l!=' ')
                .sort()
              )
            ];
      return JSON.stringify(newStr) === JSON.stringify(alphabet) || newStr.length;
    }
    

    Note

    This solution is working for sentance as well.

    Explanation

    As you can see I used method chaining when assigning the newStr variable and that part might be confusing. So lets decompose it:

    • string.ToLowerCase() - When we compare the word we need it to be in lowercase

    • .split - Here we start chaining the methods. The returned string ( from string.ToLowerCase() ) we are spliting it into an array. This is equal to:

      let str1 = str.toLowerCase();

      str1 = str1.split();

    • .filter(l => l != ' ') - go thru every letter in the array ( labeling it as l ) and return only letters that are not an empty space. Filter returns an array.

    • .sort - sort the returned array.

    • new Set() - The returned array, we are using it as an argument to the set object.Set object is a collection of values that can occur only once. We create this object so we have only unique letters

    • [...] - Using the spread syntax we are spreading the set object into an array. We need it as an array so we can compare it with the alphabet

    The return part

    We cant compare two arrays with == or === because the equality operator will check if the arrays are the same instance( only arr1 === arr1 ). Therefore we need a way around. I choose to stringify them, but there are many ways you can do it.

    return JSON.stringify(newStr) === JSON.stringify(alphabet) || newStr.length;
    

    So if newStr is equal to alphabet we return true, if not we are returning the length of newStr.

    Improvement

    There are many solutions to every problem, and each of them can be improved. In this particular case I would say that before comparing, we can check if the length of the arrays are the same. If they are not we just return the length. note: avoid nesting ternary operators

    return newStr.length != alphabet.length ? newStr.length :
      JSON.stringify(newStr) === JSON.stringify(alphabet) ? true : newStr.length;