Reputation: 1011
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
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
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
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
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