Function to return letter frequencies in an array

Asked

Viewed 1,087 times

3

I was trying to do the function that is in the title, but I did not succeed, looking at the solution code for such function, I could not understand, follow the code:

    function letter_frequency(s) {
    let arr = [];
    let i = 0;
    let str = s.toUpperCase();
    while (i < str.length){
        let char = str.charAt(i);
        if (arr[char]!== undefined){
            arr[char]++;
        } else arr[char] = 1;

        i++
    }
    return arr;
}

My question refers to the if. Let’s say we get a String "hello". Because the letter H (charAt[i] para i = 0;) is considered undefined?

  • JS has some weird things and I may not know one of them, but for me this is bad code and it doesn’t make sense. o s can be undefined. The code is so bad it makes two loops where it could make one, and the person who made it didn’t realize it, must have put this if cheerful also because he saw something similar somewhere that manipulated another type of object.

  • The misspelled ta code will never have the effect of counting frequency.

  • It’s not the letter H that’s being compared to undefined, and yes arr["H"]. Basically, arr[letra] keeps the quantity of that letter, but if it is the first occurrence of that letter, arr[letra] it does not yet exist, so it is verified whether it is undefined

  • Now that I’ve seen that he’s using it as a dictionary.

  • 1

    I understood the question is not "why the code does not work" but "why the tested letter is Undefined"

  • It loops the string of the word and when it does not find a letter in the string, that is, while it nay for Undefined, meaning that the letter does not exist in the string, it defines that the frequency is 1 (once). Otherwise, it sums up the amount of times the letter repeats in the string, removes the Let and uses var... to understand: use: 'hello'. charAt(0); 'hello'. charAt(1);

  • Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site.

Show 2 more comments

3 answers

3


The if in itself there is testing a condition of a dictionary. A dictionary is an object that has several elements indexed by a key and this key can be any valid value.

He looks a little like a array, but it’s different because in array the key is called index, only accepts an integer numeric value in sequence, in the case of JS starting at 0 and ending at number equal to size minus 1. In the array all keys within this range are valid keys in a dictionary (also known as hashtable or array associative or map in certain contexts) does not have a sequence, the keys are sparse so any key may or may not exist in this data collection. So these collections are a pair of key and value, where what you’re most interested in is the value, but it’s accessed through the key.

The Javascript API has chosen that if you try to access a non-existent key, it only results in a value undefined because if you don’t have the key of course you don’t have the value. So the way to check if the key doesn’t exist is to exactly see if the resulting value is undefined.

In this code you are taking a letter of the received parameter and checking if it exists in the data collection, if it does not exist then the key is created with an initial value of 1, if it already exists then just increments the value there. So this collection will have an element for each different letter existing in string passed, when the letter is repeated instead of creating a new key it increments the letter counter and thus gets what is expected, the letter frequency count.

You can do it better, but it’s a valid way.

So visualize what happens:

 function letter_frequency(s) {
    let arr = [];
    for (let chave in s) {
        let char = s[chave].toUpperCase();
        if (arr[char] !== undefined) arr[char]++;
        else arr[char] = 1;
        for (let chave in arr) console.log(chave, "=>", arr[chave]);
        console.log("------");
    }
    return arr;
}

letter_frequency("Hello");

I put in the Github for future reference.

2

Because the solution uses a array, arr, as a map, the key being the letter present in string and its value will be the amount it repeats. Initially this array is empty and therefore there will be no letter associated with it. This implies that arr['h'] return undefined.

let arr = [];

console.log(arr['h']);

So if it is undefined, the index in the array and initialized with the value 1. In the next iterations the index will exist and will not return undefined and when that happens it will only increase the value.

let arr = [];

arr['h'] = 1;

console.log(arr['h']);

That is, by going through the letters of string will always be returned undefined when it is the first occurrence of it. In the next it will only be increased the amount.

Using the Map

An alternative would be to use the type itself Map to create this map:

function frequency(text) {

  // Define o mapa que gerenciará as frequências
  const map = new Map();
  
  // Percorre as letras do texto
  for (let letter of text) {
  
    // Busca a quantidade de vezes que a letra já se repetiu, ou 0 para a primeira ocorrência
    let count = map.get(letter) || 0;
    
    // Atualiza a frequência incrementando-a
    map.set(letter, count+1);
  }
  
  // Retorna o mapa de frequências
  return map;
}

const frequencies = frequency("anderson");

// Exibe a frequência de cada letra
for (let [letter, total] of frequencies) {
  console.log(`A letra ${letter} repetiu ${total} vezes.`);
}

1

Hey, buddy, here’s the deal:

It checks while the letter array "nay" is undefined, that is, when it enters the rule of counting and starts to add up the values. The letter H in the case is defined, that is, opposite of what you are saying. and is not an array as you published, of the type: charAt[i], even behaving as such, this is a function of javascript, which captures the position of the letter in the string:

For example: 'Hello'.charAt(0) irá retornar "H"; The function String.charAt() return the letter at the position of the string [0 => 'H', 1 => 'E', 2 => 'L', ...]

if in the case is testing the letter, consider that i is 0, then in the variable char will have the letter "H", it is undefined, right, then it enters into Isis, the [denied+equal+equal] ( !== ) is checking if it is different both the type, and its value.

That is, if it is an "H" it enters the Else and receives the value 1:

 let char = str.charAt(i);

`else arr[char] = 1;`

The while is increasing the variable i , while it is less than the total of letters of the word, this causes it to traverse letter to letter and assign the values of the sum to defined elements, in all other situations will be undefined, and will receive the value 1:

 if (arr[char]!== undefined){
     arr[char]++;
 } 

Note that while does this for each letter:

arr[char]will add up when it is set:

arr["H"]++
arr["E"]++
arr["L"]++ //aqui fará uma soma de vezes pois ele terá sido definido mais de uma vez
arr["O"]++

He’ll go through the assignment rule five times:

First you will enter Isis, since arr[char] not yet defined, returning the value 1 to the position of the letter H.
2nd will enter the E-this, since arr[char] not yet defined, returning the value 1 to the position of the letter E.
3rd will enter the Else, since arr[char] not yet defined, returning the value 1 to the position of the letter L.
4º enters the if condition, once it has already defined arr[char] with the letter L, it will add up: 2
5º enters Else again because the letter O has not yet been defined and puts the value 1.

You can test and see it happen as follows in your browser console:

function letter_frequency(s) {
    let arr = [];
    let i = 0;
    let str = s.toUpperCase();
    while (i < str.length){
        let char = str.charAt(i);
        if (arr[char]!== undefined){
            arr[char]++;
            console.log('definido',  arr[char], char)
        } else {arr[char] = 1;
            console.log('indefinido',  arr[char], char)
        }


        i++
    }
    return arr;
}
letter_frequency("Hello");

Browser other questions tagged

You are not signed in. Login or sign up in order to post.