Reputation: 532
I have written down code to calculate the count of each of the character in a string. It seems to be working correctly for some of the words where as for some it fails.
It fails for the last character, as I see the length of the string becomes smaller than the iteration count (but for some of the words)
var str1 = "america"
function noofchars(str1) {
for (var m = 0; m < str1.length + 1; m++) {
var countno = 1;
if (m != 0) {
str1 = str1.slice(1)
}
str2 = str1.substr(0, 1)
for (var i = 0; i < str1.length; i++) {
if (str2 === str1.charAt(i + 1)) {
countno += 1
str1 = str1.slice(0, i + 1) + str1.slice(i + 2) + " "
}
}
console.log(str1.charAt(0) + "=" + countno)
}
}
var findnoofchar = noofchars(str1)
It passes for london, philadelphia, sears, happy But fails for america, chicago etc london = l=1, o=2, n=2, d=1
Upvotes: 2
Views: 636
Reputation: 21
Not really knowing what you are trying to accomplish with your code, one solution is to utilize the charAt and Set functions. CharAt is a more direct way to iterate over the string and the Set function eliminates duplicate characters from the set automatically.
var str1 = "america";
function noofchars(str1) {
var charList = new Set();
for (var m = 0; m < str1.length; m++) {
var charX = str1.charAt(m).substr(0, 1);
var countno = 1;
for (var i = 0; i < str1.length; i++) {
if (str1.slice(0, i + 1) == charX) {
countno++;
}
charList.add(charX + "=" + countno);
}
}
// you may need to expand set on Chrome console
console.log(charList);
// a hack to display more easily display on your screen
var listOnScreen = Array.from(charList);
document.getElementById('displaySet').innerHTML=listOnScreen;
}
noofchars(str1);
<div id="displaySet"></div>
Upvotes: 0
Reputation: 2970
You can split the string by each character and then count the number of occurrence of each character by reduce
function as below
function noofchars(str1) {
const chArray = str1.split('');
return chArray.reduce(function(acc, ch) {
if (acc[ch]) {
acc[ch]++;
} else {
acc[ch] = 1;
}
return acc;
}, {});
}
var str1 = "america";
var findnoofchar = noofchars(str1);
console.log(findnoofchar);
In your solution you are mutating str1
in this line
str1 = str1.slice(0, i + 1) + str1.slice(i + 2) + " "
which actually changes the length of the string and also checking str1.length
in the first loop. In you case you can take the length in the first place. Working version of your code snippet is here
var str1 = "america"
function noofchars(str1) {
const len = str1.length;
for (var m = 0; m < len; m++) {
var countno = 1;
if (m !== 0) {
str1 = str1.slice(1)
}
if (str1.charAt(0) === ' ') {
break;
}
str2 = str1.substr(0, 1)
for (var i = 0; i < str1.length; i++) {
if (str2 === str1.charAt(i + 1)) {
countno += 1
str1 = str1.slice(0, i + 1) + str1.slice(i + 2) + " "
}
}
console.log(str1.charAt(0) + "=" + countno)
}
}
var findnoofchar = noofchars(str1)
Upvotes: 0
Reputation: 44145
It'd be easier to use an object. First reduce
into character counts, then iterate through the key/value pairs and console.log
:
function noofchars(str1) {
let r = [...str1].reduce((a, c) => (a[c] = (a[c] || 0) + 1, a), {});
Object.entries(r).forEach(([k, v]) => console.log(`${k}=${v}`));
}
noofchars("america");
ES5 syntax:
function noofchars(str1) {
var r = str1.split("").reduce(function(a, c) {
a[c] = (a[c] || 0) + 1;
return a;
}, {});
Object.keys(r).forEach(function(k) {
console.log(k + "=" + r[k]);
});
}
noofchars("america");
It's easier to understand what reduce
is doing in the above snippet.
First, we take a function with two parameters a
and c
. These can be called anything, I just use a
and c
for the accumulator and the current item.
Now, the second line:
a[c] = (a[c] || 0) + 1;
This is kind hard, so let's break it down. First let's look at what's in the parentheses:
a[c] || 0
This checks if a
has a key/value pair with the key c
(as in, the value of c
, not the key literally being c
). If that doesn't exist, it returns 0
. So if a[c]
exists, save it as the value of the expression, otherwise use 0
.
Now, we add 1
, to increment the value.
Finally, we assign the result to a[c]
. So if a
contained c
, the value of a[c]
would be incremented. If a
didn't contain c
, the value of a[c]
would be 1
.
Then, we return a
to be used in the next iteration of reduce
.
In the next line:
}, {});
We assign a default value for a
. If we didn't do this, the first time reduce
ran, a
would be "a"
, and c
would be "m"
(the first two characters of america
). This way, a
is {}
(an empty object), and c
is "a"
. If we didn't have this second argument, our function wouldn't work.
In this line:
Object.keys(r).forEach(function(k) {...});
We're getting an array of all the keys in r
, and looping through them with forEach
, with k
being the key.
Then, we're logging k
(the key), then an equals sign =
, then the value of r[k]
.
Upvotes: 5