0

I'm new on this and javascript. I've tried to solve an exercise that consist to find repeated letter a in an array. The way to do is use basic structures (no regex neither newer ways of javascript (only ES5)). I need to do it this way to understand the bases of the language.

The output must be this:


//Captain America, the letter 'C' => 2 times.
//Captain America, the letter 'A' => 4 times.
//Captain America, the letter 'I' => 2 times.

I'm not looking for the solution, only the way to do it and its logical structures. Any suggestions are welcome.

My way but it doesn't work:

function duplicateLetter(name) {
  var newArray = [];

  for (var i=0; i<name.length; i++) {
    console.log(name[i].indexOf(newArray));

    if (name[i].indexOf(newArray) === 0) {
        newArray.push(name[i]);
    }
  }

   console.log(newArray);   

  //console.log(name + ", the letter '" + (newArray[0]).toUpperCase() + "' => " + newArray.length + " times");
}

duplicateLetter("Captain America");
3
  • 1
    Make a loop, make a counter for each character you want to count. That'st the way Commented Apr 21, 2018 at 23:08
  • 1
    Where is the source code of your attempt(s)? Please edit/update your question with the relevant source code. Commented Apr 21, 2018 at 23:09
  • 1
    You're right @GeorgeBailey. I've posted the code right now. Thanks! Commented Apr 21, 2018 at 23:20

2 Answers 2

2
function duplicateLetter(o) {
    var arr = o.toUpperCase().split('');
    var obj = {};

    for(var v in arr) {
        obj[arr[v]] = obj[arr[v]] || 0;
        obj[arr[v]]++;
    }

    for(var v in obj) {
        console.log(o + ", the letter '" + v + "' => " + obj[v] + ' times.');
    }
}

duplicateLetter("Captain America");

The explanation:

  • We make the string upper case, then turn it into an array of letters.
  • We loop over the array, here, arr[v] becomes our letter, and:
    • If the key arr[v] doesn't exist in our object, we set it to 0.
    • We increment the value of the key arr[v] in our object (this causes obj['c'] to increment every time our letter is c. You can notice that this keeps track of the number of letters in our string.
  • We loop over the object v, printing the number of occurrences of each letter to console.

Note that this considers the space character as a letter. If you want an answer that doesn't, please specify so.

Here's a different answer that doesn't use objects and only counts letters (and not spaces or punctuation) to prove that everything is possible in more than one way.

// Not using objects and not counting anything but letters.
function duplicateLetter(o) {
    var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var arr = o.toUpperCase().split('');
    var count = [];

    for(var v in arr) {
        pos = letters.indexOf(arr[v]);
        if(pos < 0) continue; // It wasn't a letter.
        count[pos] = count[pos] || 0;
        count[pos]++;
    }

    for(var v in count) {
        if(!(count[v] > 0)) continue; // The letter never appeared.
        console.log(o + ", the letter '" + letters[v] + "' => " + count[v] + ' times.');
    }
}

duplicateLetter("Captain America");

I could probably also attempt an answer that doesn't use arrays at all!

Edit: You can use for(a in b) loops to iterate arrays as well as objects. This is because an array is really just an object in which all enumerable properties have integer indices:

arr = [10,15,"hi"] is almost the same as arr = {'0' : 10, '1' : 15, '2' : "hi"} in the way Javascript works internally. Therefore, for (v in arr) will iterate over the array normally.

As requested, the same answer with normal for loops:

// Not using objects and not counting anything but letters.
function duplicateLetter(o) {
    var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var arr = o.toUpperCase().split('');
    var count = [];

    for(var v = 0; v < arr.length; v++) {
        pos = letters.indexOf(arr[v]);
        if(pos < 0) continue; // It wasn't a letter.
        count[pos] = count[pos] || 0;
        count[pos]++;
    }

    for(var v = 0; v < count.length; v++) {
        if(!(count[v] > 0)) continue; // The letter never appeared.
        console.log(o + ", the letter '" + letters[v] + "' => " + count[v] + ' times.');
    }
}

duplicateLetter("Captain America");

Note that nothing changed outside what was in the for brackets. The for-in notation is just easier for the human brain to comprehend, in my opinion, and is the reason I used it.

As for count[pos] = count[pos] || 0;, explaining why it works the way it does is extremely tedious, since it requires that you know precisely what the || operator does. So I'm just going to state what it does, without explaining it.

Basically, count[pos] = count[pos] || 0; is the same as:

if(count[pos]) { // If count[pos] evaluates to true.
    count[pos] = count[pos]
} else { // count[pos] is false, '', null, undefined, 0, or any other value that evaluates to false.
    count[pos] = 0;
}

Note that this works because at the start, count[pos] is undefined (count is an empty array), so it puts a 0 in it. If we find the letter again, count[pos] is defined, and is a positive value, and therefore evaluates to true, so we don't change it.

Just consider a = a || b to be equal to:

Put the default value of b into a if a is undefined (or evaluates to false by any other means).`

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

7 Comments

Works perfect @mmdts! I have a question for you. Use objects is the only way to do this?
There is no such thing as "only way" in programming. I can attempt an answer using just arrays, and another answer using neither objects nor arrays, and succeed at both.
Perfect! Now I try to understand this and use my basic knowlegde to do the exercise on my own way. Thanks a lot!
Edited the answer to provide another one that doesn't use objects and only counts letters.
Amazing @mmdts. I understand better this way. Thanks again! II appreciate it.
|
0

Make an object whose keys are the letters and values are the number of times that letter was repeated. For example, 'abbc' => {'a': 1, 'b': 2, 'c': 1}

1 Comment

Thanks @Gjekask. Use objects is the only way to do this?

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.