Good evening, I proceed to explain my situation. I started to get interested in javascript which started to dabble in this language, I have been doing some online courses which I have encountered the following task, basically I am trying through the condition "for" tell me what is the first repeated letter of a string also adding the funsion ".UpperCase () "which at the beginning worked best, until I entered more characters to the string in this case" x "throwing me as output result" undefined "instead of" the most repeated word is: X "reach the case that the string should Consider all the letters regardless of whether they are lowercase or capital letters, for which I ask for help to understand if ¿there is another way? for this task and thus move forward (Sorry for my bad english)

Well i making this task in JavasScript with Atom Editor

var word = "SQSQSQSSaaaassssxxxY";
var contendor = [];
var calc = [];
var mycalc = 0;

function repeat() {
  for (var i = 0; i < word.length; i++) {
    if (contendor.includes(word[i])) {} else {
      contendor.push(word[i])
      calc.push(0)
    }
  }
  for (var p = 0; p < word.length; p++) {
    for (var l = 0; l < contendor.length; l++) {
      if (word[p].toUpperCase() == word[l]) {
        calc[l] = calc[l] + 1
      }
    }
  }
  for (var f = 0; f < calc.length; f++) {
    if (calc[f] > mycalc) {
      mycalc = calc[f]
    }
  }
}
repeat()

console.log("The first letter repeated its: " + contendor[mycalc])

I expected the output of the String to be: "X"

but the actual output is: "Undefined"

6 Answers

0
trincot On Best Solutions

The first error in your script is that you store the wrong value in mycalc:

  mycalc = calc[f]

Since you want mycalc to be an index, the above should have been

  mycalc = f

Now, you will get a result, but your code is actually going through a lot of effort to find the uppercase character that is repeated most often, not first.

Your comparison should have used toUpperCase on both sides of the comparison, otherwise lower case letters will never match.

To get the character that was repeated most often, you could use a Map (to keep track of the counts like you did in calc):

function mostRepeated(str) {
    const map = new Map;
    let result;
    let maxCount = 0;
    for (let ch of str) {
        ch = ch.toUpperCase();
        let count = (map.get(ch) || 0) + 1;
        map.set(ch, count);
        if (count > maxCount) {
            maxCount = count;
            result = ch;
        }
    }
    return result;
}

var word = "MBXAYMZAXmZYxxxxxxxxxxmBxAYMZaXmZY";
console.log(mostRepeated(word));

Note that you should better use function parameters and local variables. Declaring your variables as global is not considered best practice.

0
Eddie On

If you want to get the index of most repeated letter, you can use Array.from to convert the word into an array. Add a map function to make all letters uppercase.

Get the count of each letter by using reduce and Object.entries

Use indexOf to the get the index of the lettet in the array. Please note that indexOf count the letters from 0.

var word = "MBXAYMZAXmZYxxxxxxxxxxmBxAYMZaXmZY";
var letters = Array.from(word, o => o.toUpperCase());
var [highestLetter, highestCount]= Object.entries(letters.reduce((c, v) => (c[v] = (c[v] || 0) + 1, c), {})).reduce((c, v) => c[1] > v[1] ? c : v);
var index = letters.indexOf(highestLetter);

console.log("Most repeated letter:", highestLetter);
console.log("Count:", highestCount);
console.log("First Index:", index);

0
Dacre Denny On

You could find the letter that occurs the most number of times in a string by:

  1. first creating a map that relates each unique letter, to the number of times it occurs in the string
  2. converting that map to an array of "key/value" entries, and then sorting those entries by the "count value"
  3. returning the "letter key" that has the largest count

One way to express this in JavaScript would be via the following:

function findMaxLetter(word) {

  /* Create a map that relates letters to the number of times that letter occours */
  const letterCounts = Array.from(word).reduce((map, letter) => {
    
    return { ...map, [letter] : (map[letter] === undefined ? 0 : map[letter] + 1) }
    
  }, {})
  
  /* Sort letters by the number of times they occour, as determined in letterCounts map */
  const letters = Object.entries(letterCounts).sort(([letter0, count0], [letter1, count1]) => {
    
    return count1 - count0
    
  })
  .map(([letter]) => letter)
  
  /* Return letter that occoured the most number of times */
  return letters[0]
}

console.log("The first letter repeated its: " + findMaxLetter("MBXAYMZAXmZYxxxxxxxxxxmBxAYMZaXmZY"))

0
Lev Buchel On

console.log("The first letter repeated its: " + contendor[mycalc]) You tried to print the 14th index of contendor which has only 9 values, that is why your log result was undefined.

You probably wanted to print word[mycalc].

Also if you intended to count x as X, you should have added toUpperCase() to every letter you process/go-through.

This is only a note to the issues in your code, there are better/faster/cleaner solutions to reach the result which i am sure other answers will provide.

0
azad On

I this is solution is most detailed for you

function func( word ){

    word = word.toLowerCase();

    var i, charCountCache = {};

    //store all char counts into an object
    for( i = 0; i < word.length; i++){

      if( charCountCache[ word[ i ] ] )
        charCountCache[ word[ i ] ] = charCountCache[ word[ i ] ] + 1;
      else
        charCountCache[ word[ i ] ] = 1;
    }

    //find the max value of char count in cached object
    var fieldNames = Object.keys( charCountCache )
    , fieldValues  = Object.values( charCountCache )
    , mostReapeatChar = '', mostReapeatCharCount = 0;


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

        if( mostReapeatCharCount < fieldValues[i] ){
          mostReapeatCharCount = fieldValues[i];
          mostReapeatChar = fieldNames[i];
        }

      }    

    console.log('most repeating char: ', mostReapeatChar, ' no of times: ', mostReapeatCharCount )
  }
0
Wonkledge On

my advice would be to create a hashmap such as letter => [indexLetter1, indexLetter2].

From that hashmap, you could easily find your first repeated letters.

For that string MBXAYMZAXmZYxxxxxxxxxxmBxAYMZaXmZY, hashmap will look like

[
    M => [0,5,..],
    B => [1, ..],
    X => [2, ..],
    ...
]

now you can find every letter with multiple values in its array, then in those arrays take the one with the lowest value.