coderrick
coderrick

Reputation: 1011

Using character codes to get frequency on words in a string, JavaScript

I'm trying to rewrite this frequency finding program in Javascript. Here is the Java code:

public class frequency {
   public static void main(String[] args){
       String S = "Temple University";   
       int[] p = new int[256];
       for (char c :S.toCharArray()) {
           p[c]++;
           System.out.println(c +" shows up "+p[c] + " times");
       }

Output:

T shows up 1 times
e shows up 1 times
m shows up 1 times
p shows up 1 times
l shows up 1 times
e shows up 2 times
  shows up 1 times
U shows up 1 times
n shows up 1 times
i shows up 1 times
v shows up 1 times
e shows up 3 times
r shows up 1 times
s shows up 1 times
i shows up 2 times
t shows up 1 times
y shows up 1 times

However, my JavaScript implementation doesn't work at all:

  function frequency(){
  s = "Temple University";
  str = s.split('');
  p = [];
  p.length = 256;
  console.log("start");
  for(c in str){
    p[c]++;
    console.log("inside" + c);
    console.log(String.fromCharCode(c) + " shows up " + p[c] + "times");
  }
}

It's late I've been trying to figure out why this JavaScript code is not working so I'm sorry if this post seems unpolished.

Upvotes: 1

Views: 95

Answers (4)

Redu
Redu

Reputation: 26171

You may do as follows;

var s = "Temple University",
 fmap = Array.prototype.reduce.call(s,(p,c) => (p[c] ? p[c]++ : p[c] = 1,p),{});
for(var i in fmap) console.log(i, "shows up", fmap[i],"times.");

We are using an array functor Array.prototype.reduce() over a string by using a Function method .call(). So the first argument passed to .call() is the string s itself (designating the context to be called upon) and a callback ((p,c) => (p[c] ? p[c]++ : p[c] = 1,p)) for the second argument to be invoked per item (character) of the string. The .reduce() functor uses an empty object {} as an initial value which will be assigned to p, whereas c would be assigned to the first character in the first turn. It will generate a map called fmap like;

{ T: 1,
  e: 3,
  m: 1,
  p: 1,
  l: 1,
  ' ': 1,
  U: 1,
  n: 1,
  i: 2,
  v: 1,
  r: 1,
  s: 1,
  t: 1,
  y: 1 }

Then a for in loop traverses over the map keys and we display the obtained data by a console.log() instruction.

Upvotes: 0

furkle
furkle

Reputation: 5059

The main reason this isn't working is that for loops work differently in Javascript than in Java. In Javascript, a for-in loop iterates through the properties of an object, not the indices of an array or string, so rather than for-in, you'd want to use a plain for loop, like so:

function getFrequencies(string) {
    if (typeof(string) !== 'string') {
         throw new Error('string argument is not of type string.');
    }

    var str = string.split('');
    var frequencies = {};
    for (var c = 0; c < str.length; c++) {
        var charCode = String.fromCharCode(str[c]);
        if (!frequencies[charCode]) {
            frequencies[charCode] = 1;
        } else {
            frequencies[charCode]++;
        }
    }

    return frequencies;
}

A couple tips: you would want to use a plain object ({}) instead of an array ([]), given that you're counting unique values. Secondly, there's no need to declare the length of an array in Javascript -- arrays are automatically resized as they grow, and the length property is readonly anyway.

Upvotes: 1

Z-Bone
Z-Bone

Reputation: 1584

Does this work for you? If so, you just weren't referencing the charCode but the index of the letter in the string..

function frequency() {
	s = "Temple University";
	str = s.split('');
	p = [];
	p.length = 256;
	console.log("start");
	for (c in str) {
		var curChar = str[c];
		var charCode = curChar.charCodeAt();
		p[charCode] ? p[charCode]++ : p[charCode] = 1;

		console.log(curChar + " shows up " + p[charCode] + " time(s)");
	}
}

frequency()

Upvotes: 1

Vinod Louis
Vinod Louis

Reputation: 4876

You can manipulate string directly as array and need a safe check for occurrence of chars else assign value 1.

So use a for loop for iterating over whole string can extract char as s[index] while using p[char] for occurrence frequency.

sample code follows

function frequency(){
  s = "Temple University";
  p = [];
  console.log("start");
  for(var i=0;i<s.length;i++){
    if(!p[s[i]]){
      p[s[i]] = 1;
    }else{
      p[s[i]]++;  
    }
    console.log(s[i] + " shows up " + p[s[i]] + "times");
  }
}

frequency()

Upvotes: 1

Related Questions