Reputation: 461
I am trying to count letters in a text and get an object to display the letter count for each word.
So, for input "Argument here"
expected output would be:
{ Argument: { A: 1, r: 2, g: 1, u: 1, m: 1, e: 3, n: 1, t: 1, ' ': 1, h: 1 },
here: { e: 2, h: 1, r: 1} }
My attempt:
function LetterCountI(str) {
var arr = str.split(" "); var cCount = {}; var anotherO = {}; var final = {};
for(var i = 0; i < arr.length; i++){
if(cCount[arr[i]]){
cCount[arr[i]]++;
} else {
cCount[arr[i]] = 1;
}
}
var letterCount = str.split("");
for(var j = 0; j < letterCount.length; j++){
if(anotherO[letterCount[j]]){
anotherO[letterCount[j]]++;
} else {
anotherO[letterCount[j]] = 1;
}
}
for(var property in cCount){
final[property] = anotherO;
}
return final;
}
LetterCountI("Argument here");
What I currently get is
{ Argument: { A: 1, r: 2, g: 1, u: 1, m: 1, e: 3, n: 1, t: 1, ' ': 1, h: 1 },
here: { A: 1, r: 2, g: 1, u: 1, m: 1, e: 3, n: 1, t: 1, ' ': 1, h: 1 } }
Upvotes: 2
Views: 2700
Reputation: 586
Using forEach is an easier method, but here's something a bit more vanilla:
function countLetters(string) {
var obj = {};
var arr = string.split(' ');
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = {};
for (var j = 0; j < arr[i].length; j++) {
if (!obj[arr[i]][arr[i][j]]) {
obj[arr[i]][arr[i][j]] = 1;
} else {
obj[arr[i]][arr[i][j]]++;
}
}
} return obj;
}
console.log(countLetters("Argument here"));
Upvotes: 0
Reputation: 24551
First of all, your approach can fail. If your text just for fun contains __proto__
or another Object
property this property will give you an error / unexpected result. Anyway, if you are still sure you want to use this method instead of e.g. hash maps, you can go on with solutions below.
If you care about faster way of doing this you can use the following code:
function count(string) {
var tmpname = '', tmpvalue = {}, result = {}, i = string.length;
while (i--) {
var letter = string[i];
if (letter === ' ') {
result[tmpname] = tmpvalue;
tmpname = '';
tmpvalue = {};
}
else {
tmpname = letter + tmpname;
tmpvalue[letter] = (tmpvalue[letter] || 0) + 1;
}
}
if (tmpname) {
result[tmpname] = tmpvalue;
}
return result;
}
console.log(count("Argument here"));
This does not call split
function, so it is theoretically faster than Max Mastalerz's solution which does at least 2 full loops by calling a split
function two times. If you don't really care about performance or your texts are usually very short, you can use a bit shorter version of Max Mastalerz's solution to approach this:
function count(string) {
return string.split(' ').reduce(function(a, b) {
b.split('').reduce(function(c, d) {
return (c[d] = (c[d] || 0) + 1 , c);
}, a[b] = {});
return a;
}, {});
}
console.log(count("Argument here"));
It is doing just the same, first finding the words and then finding the letters of each word.
Upvotes: 1
Reputation: 2816
JSFiddle, The following will count letters in the words that make up a string:
function letterCounts(s) {
var result = {};
s.split(' ').forEach(function(e) {
result[e] = {};
e.split('').forEach(function(c) {
if(!result[e][c]) { result[e][c]=0; }
result[e][c]++;
});
});
return result;
}
letterCounts('Argument Here');
The result is:
"{"Argument":{"A":1,"r":1,"g":1,"u":1,"m":1,"e":1,"n":1,"t":1},"Here":{"H":1,"e":2,"r":1}}"
Upvotes: 4