0

I have a problem. I'm trying to create a function that return the number of letters of frequency of a particular string. Here is an example.

var a = letter_frequency("Hello");
a["H"] == 1; a["E"] == 1; a["L"] == 2; a["A"] == undefined;

Now I have the code I wrote but I don't know how to go forward. Can you help me?

    function letter_frequency(s) {
    if (s === undefined) {
        return undefined;
    } else {
        var splitter = s.split()

    }
}

Here one test

 test( "Frequency", function() {
    deepEqual(letter_frequency() , undefined);
    var a = letter_frequency("Hello");
    equal(a["H"] , 1, "For the String 'Hello' the number of 'H' chars should be 1");
    equal(a["E"] , 1, "For the String 'Hello' the number of 'E' chars should be 1");
    equal(a["L"] , 2, "For the String 'Hello' the number of 'L' chars should be 2");
    equal(a["O"] , 1, "For the String 'Hello' the number of 'O' chars should be 1");
    deepEqual(a["A"] , undefined, "For the String 'Hello' the number of 'A' chars should be undefined");
    var a = letter_frequency("Software Atelier III");
    equal(a["I"] , 4, "For the String 'Software Atelier III' the number of 'I' chars should be 4");
    equal(a["S"] , 1, "For the String 'Software Atelier III' the number of 'S' chars should be 1");
    equal(a["A"] , 2, "For the String 'Software Atelier III' the number of 'A' chars should be 2");
    equal(a["O"] , 1, "For the String 'Software Atelier III' the number of 'O' chars should be 1");
    equal(a["T"] , 2, "For the String 'Software Atelier III' the number of 'T' chars should be 2");
    equal(a[" "] , 2, "For the String 'Software Atelier III' the number of ' ' chars should be 2");
    equal(a["F"] , 1, "For the String 'Software Atelier III' the number of 'F' chars should be 1");
    equal(a["W"] , 1, "For the String 'Software Atelier III' the number of 'W' chars should be 1");
    equal(a["T"] , 2, "For the String 'Software Atelier III' the number of 'T' chars should be 2");
    equal(a["L"] , 1, "For the String 'Software Atelier III' the number of 'L' chars should be 1");
});

SOLUTION: Thanks to h2ooooooo

So for my code I used

function letter_frequency(s) {
if(s === undefined){
    return undefined
} else {
    var fr = {};
    for (var i = 0; i < s.length; i++) {
        var ch = s.charAt(i).toUpperCase();
        if (fr[ch]) {
            fr[ch]++;
        } else {
            fr[ch] = 1;
        }
    }
}
    return freq;
}

I linked some code from all the answer I received. The only difference is the control for the undefined question where my exercise asked for a control with undefined words

pp94
  • 133
  • 5
  • 19
  • And this is supposed to be case-insesitive, and return uppercase letters only? Strange thing to do? – adeneo Sep 25 '14 at 17:32
  • 2
    Seems like a dupe of http://stackoverflow.com/questions/18619785/counting-frequency-of-characters-in-a-string-using-javascript – j08691 Sep 25 '14 at 17:33
  • I thing is only upper case. It is an exercise I find in a book of JavaScript. I started yesterday to study it. I know it can be a stupid question... – pp94 Sep 25 '14 at 17:33
  • http://jsfiddle.net/421qd4n7/ – adeneo Sep 25 '14 at 17:36
  • @j08691 not completely a dupe because in that problem it just find 1 letter (the first) instead of all – pp94 Sep 25 '14 at 17:36

2 Answers2

1

You can split up the string using .split() and loop through the letters:

function letter_frequency(str) {
    var letters = str.split(''),
        letterFrequency = {};

    for (var i = 0, len = letters.length; i < len; i++) {
        if (!letterFrequency.hasOwnProperty(letters[i])) {
            letterFrequency[letters[i]] = 1;
        } else {
            letterFrequency[letters[i]]++;
        }
    }

    return letterFrequency;
}

letter_frequency("Hello");
// Object {H: 1, e: 1, l: 2, o: 1}

If you'd rather have it all be capital letters (for some odd reason), you can do the following using .toUpperCase():

function letter_frequency(str) {
    var letters = str.split(''),
        letterFrequency = {},
        letter;

    for (var i = 0, len = letters.length; i < len; i++) {
        letter = letters[i].toUpperCase();
        if (!letterFrequency.hasOwnProperty(letter)) {
            letterFrequency[letter] = 1;
        } else {
            letterFrequency[letter]++;
        }
    }

    return letterFrequency;
}

letter_frequency("Hello");
// Object {H: 1, E: 1, L: 2, O: 1}
h2ooooooo
  • 39,111
  • 8
  • 68
  • 102
  • Yeah it's works in part because the exercise uses only upper case letters. In python there is .upper(). What can I use in javascript? – pp94 Sep 25 '14 at 17:38
  • yep I saw thanks. But now why the test case says TypeError: undefined is not a function?? – pp94 Sep 25 '14 at 17:41
  • @pp94 You can click the line number on the right. What line is it on? It might be because `str` is not a string. – h2ooooooo Sep 25 '14 at 17:42
  • at the toUpperCase. After the point used to call the function – pp94 Sep 25 '14 at 17:45
  • @pp94 What's your input string? – h2ooooooo Sep 25 '14 at 17:45
  • @pp94 `"Hello"` works completely fine (it does for me). What are you using to execute this? What does `console.log(typeof(letters[i]), letters[i])` output (after the letter has been set)? – h2ooooooo Sep 25 '14 at 17:48
  • This is a standard test created by the book. The function should be implemented on this type of code – pp94 Sep 25 '14 at 17:49
  • Yes, but how are you testing it, and what does the `console.log` call output? – h2ooooooo Sep 25 '14 at 17:50
  • I'm working on html so the console is in google chrome. If you prefer I can add an image of the console error – pp94 Sep 25 '14 at 17:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/61931/discussion-between-h2ooooooo-and-pp94). – h2ooooooo Sep 25 '14 at 17:52
0

Something like this should achieve what you're looking for (I based it upon the example output you provided, with the letters returned as uppercase properties of an object):

String.prototype.countLetters = function() 
{
    var arr = new Array(),
        letters = this.split('');

    for(var i = 0; i < letters.length; i++)
    {
        var letter = letters[i].toUpperCase();

        if(arr[letter] !== undefined)
        {
            arr[letter]+= 1;
        }
        else
        {
            arr[letter] = 1;
        }
    }

    return arr;
}

You can then call this using 'Hello'.countLetters();. Given this example, and using the test string of Hello, we get the following output:

[ H: 1, E: 1, L: 2, O: 1 ]

jsFiddle Demo

BenM
  • 52,573
  • 26
  • 113
  • 168