Michael Dobbertin
Michael Dobbertin

Reputation: 77

Determining character frequency in a string (Javascript)

I'm working on a solution for determining character frequency in a string. The characters are being added to my object properly but all counts end up as NaN. (I think I'm taking a less efficient approach by splitting the string into an array of characters, but I'd like to solve this approach nonetheless.)

var charFreq = function (frequencyString) {
    var stringArray = frequencyString.split("");
    var frequencies = {};
    for (var k in stringArray) {
        var nowLetter = stringArray[k];
        if (stringArray.hasOwnProperty(k)) {
            frequencies[nowLetter] += 1;
        }
    }
    return frequencies;
}

charFreq("what is the reason for this"); 

Upvotes: 5

Views: 3319

Answers (8)

dhwajGupta
dhwajGupta

Reputation: 1

function calculateFrequency(string) {
const alphabet ='abcdefghijklmnopqrstuvwxyz'
const alphabetUp = alphabet.toUpperCase()
let freq=[26] 
for(let i in alphabet){
   freq[i]=0
    for(let j in string ){
         if(alphabet[i] == string[j] || alphabetUp[i] == string[j] ){
        freq[i] = freq[i] + 1
        }
    }

    if(freq[i] != 0){
        console.log(alphabet[i] + ' : ' + freq[i])
    }
 }
}

This approach gives character count irrespective of case (upper-lower)

Upvotes: 0

Hrushikesh Nayak
Hrushikesh Nayak

Reputation: 1

function highestFreqChar(str) {
    var charMap = {};
  for (var i=0; i<str.length; i++) {
    var character = str.charAt(i);
    if (charMap[character]) {
        charMap[character]++;
    } else {
        charMap[character] = 1;
    }
  }

  var max = -1;
  var result = "";
  for (var j=0; j<str.length; j++) {
    if (max < charMap[str.charAt(j)]) {
        max = charMap[str.charAt(j)];
      result = str.charAt(j);
    }
  }
  return {result : result, charmap: charMap};
}

Upvotes: 0

David
David

Reputation: 2252

An Introduction to Functional Programming - Coding School Presentation with fat arrows =>:

var charFreq = (string) =>
   string
        .split('')
        .sort()
        .join('')
        .match(/(\w)\1*/g)
        .map(letters => [letters[0], letters.length])
        .sort((a,b) => {
                return a[1] !== b[1] ? (a[1] < b[1]) : (a[0] > b[0]);
        })

console.log(charFreq('what is the reason for this'));

Upvotes: 0

kennebec
kennebec

Reputation: 104780

You can step through the characters without making an array.

var charFreq= function(frequencyString){
    var next, i= 0, frequencies= {},
    L= frequencyString.length;
    while(i<L){
        next= frequencyString.charAt(i++);
        if(!frequencies[next]) frequencies[next]= 0;
        ++frequencies[next];
    }
    return frequencies;
}

//demo 
JSON.stringify(charFreq("what is the reason for this"));

/*  returned value: (String)
{"w":1,"h":3,"a":2,"t":3," ":5,"i":2,"s":3,"e":2,"r":2,"o":2,"n":1,"f":1}

*/

Upvotes: 0

Derek 朕會功夫
Derek 朕會功夫

Reputation: 94319

frequencies[nowLetter] is undefined in your code.

A better approach:

function charFreq(txt){
    var obj = {};
    for(var i = 0; i < txt.length; i++){
        obj[txt[i]] = ++obj[txt[i]]||1;
    }
    return obj;
}

Upvotes: 3

Whymarrh
Whymarrh

Reputation: 13575

There are many approaches, especially if efficiency is not a concern:

var frequencies = function (s) {
    var f = {};
    s.split("").forEach(function (e, i, a) {
        f[e] = f[e] || 0;
        f[e] += 1;
    });
    return f;
}

And calling frequencies("thiss") would result in Object {t: 1, h: 1, i: 1, s: 2}.

Upvotes: 1

Jeremy J Starcher
Jeremy J Starcher

Reputation: 23863

Because the property values in frequencies have an initial value of undefined and undefined + 1 == NaN

Try code like this:

var charFreq = function (frequencyString) {
    var stringArray = frequencyString.split("");
    var frequencies = {};
    for (var k in stringArray) {
        var nowLetter = stringArray[k];
        if (stringArray.hasOwnProperty(k)) {

            // One way to initialize the value -- not the only way.
            if (!frequencies[nowLetter]) {
              frequencies[nowLetter] = 0;
            }

            frequencies[nowLetter] += 1;
        }
    }
    return frequencies;
}

Upvotes: 3

jacquard
jacquard

Reputation: 1307

Your frequencies is an object and when you access

frequencies[nowLetter] += 1;

you are accessing a previously unavailable property like frequencies.a which will be undefined. Hence you are getting NaN.

See http://jsfiddle.net/xbUtR/ for the fix.

if(frequencies[nowLetter] === undefined)
                frequencies[nowLetter] = 0;
            frequencies[nowLetter] += 1;

Upvotes: 4

Related Questions