Creating a frequency listing of characters - javascript

charFreq function that's not quite working out. Hit a wall. I know I may need to
do a conditional. Calling the function returns an Object error. I'm attempting
to get string into an empty object displaying the characters like this - Object
{o: 4, p: 5, z: 2, w: 4, y: 1…}. New to Javascript by the way.
Just realized I shouldn't be appending anything. Do I need to do a .push() to
push the array into the object?
function charFreq (string){
var emptyObj = {};
for(var i = 0; i < string.length; i++) {
// console.log(string.charAt(i));
var args = [string.charAt(i)];
var emptyArr = [''].concat(args);
emptyObj += emptyArr
}
return emptyObj
}
undefined
charFreq('alkdjflkajdsf')
"[object Object],a,l,k,d,j,f,l,k,a,j,d,s,f"

You just need to set emptyObj's key of that specific letter to either 1 if it doesn't exist or increment the count if it already does.
function charFreq(string) {
var obj = {};
for (var i = 0; i < string.length; i++) {
if (!obj.hasOwnProperty(string[i])) {
obj[string[i]] = 1;
} else {
obj[string[i]]++;
}
}
return obj;
}
console.log(charFreq('alkdjflkajdsf'));

Try this instead: you need to create an object property first, then increment it. What you do, is implicitly convert the object to a string and concatenate more string data to it (using += and concat).
This is a simple approach:
function charFreq(string){
var emptyObj={};
for(var i=0; i<string.length; i++) {
if(!emptyObj.hasOwnProperty(string[i])){ // if property doesn’t exist
emptyObj[string[i]]=0; // create it and set to 0
}
emptyObj[string[i]]++; // increment it
}
return emptyObj;
}

A modified version of Richard Kho's code:
function charFreq(string) {
var obj = {};
for (var i = 0; i < string.length; i++) {
var c=string[i];
if (c=='') continue;
if (obj[c]==null) obj[c]=0;
obj[c]++;
}
return obj;
}

Related

Assigning value to function as object property within for loop

I am trying to create an array of objects. One object property is a function, which I want to change value of depending on which number in the array the object is.
When I try to use the 'i' value from the for loop, this is not being maintained in the function as a number. It is remaining a variable.
var array = [];
for (var i = 0; i<number; i++){
array[i].someFunction = function(i) {console.log(i)}}
However, when I call the value held in that property (i.e.):
console.log(array[2].someFunction)
It returns {console.log(i)} instead of {console.log(2)} which is what I want it to do.
Basically you had some problems in your code, like:
not defining number
using var instead of let
not defining the object
using the same value as parameter of the function
here you have the working solution.
var array = [];
// numbers was not defined.
const number = 10;
// use let instead of var
for (let i = 0; i < number; i++) {
// you are not instantiating your object, here is an example.
array[i] = {
"foo": "bar",
"index": i,
}
// you have to change i to j, because if you use i
// it will be the parameter of the function
array[i].someFunction = function(j) {
console.log('index: ', i);
console.log('parameter: ', j)
}
}
// we see the function
console.log(array[2].someFunction)
// we call the function succesfully
array[2].someFunction(100);
It's still referencing i, which has since changed to (number - 1). Save the value somewhere you know it's not subject to change- perhaps in the object itself:
var array = [{}, {}, {}];
for(var i = 0; i < array.length; i++){
array[i].index = i;
array[i].someFunction = function(){console.log(this.index);}
}
//and see that it's working...
for(var i = 0; i < array.length; i++){
array[i].someFunction();
}

iterating a string with results formmated into an object inJS

I have a function which produces the result of a string into an object with the letters counted as values of the properties in a key/value format.
var output = countAllCharsIntoObject('banana');
console.log(output); // --> {b: 1, a: 3, n: 2}
My issue is that beside the looping of an array of the string
function countAllCharsIntoObject(str){
var arr = str.split('');
var obj = {};
for(var i = 0; i < arr.length; i++) {
//how to iterate the arr[i] and assign the value of the chars to the
//keys/values of the new obj. And if more then 1 indexOf(arr[i]) then
//change through an iteration the value of the new char key.I tried so
//many solutions without effect.
}
return obj;
}
Just can not wrap my mind around the fact that i simultaneously loop within a loop with assignment to key/values of the results of the loop (with dynamic increment of values).
Any help would be appreciated!
Just in plain JS please... no underscore or lodash or jQuery solutions.
Thanks!
You just need to iterate through each character in your word and either add a new key to your object, or increment an existing key:
function countAllCharsInObject (word) {
var letterCounts = {};
var currentLetter;
for (var i = 0; i < word.length; i++) {
currentLetter = word[i];
if (currentLetter in letterCounts) {
letterCounts[currentLetter] += 1;
} else {
letterCounts[currentLetter] = 1;
}
}
return letterCounts;
}
Simplified code:
var output = countAllCharsIntoObject('banana');
console.log(output); // --> {b: 1, a: 3, n: 2}
function countAllCharsIntoObject(str) {
var arr = str;
var obj = {};
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = obj[arr[i]] + 1 || 1
}
return obj;
}

Find the length of an specific object within an array

In the following code there is a console log of obj['mn'] which returns the length of that specific object which is 2. The problem with the code is that it doesn't count the multidimentional array, and only it counts the first array. The result should be 4 because there are 4 'mn' in total. What am I doing wrong?
var arr = [['ab','pq','mn','ab','mn','ab'],'mn','mn'];
var obj = { };
for (var i = 0, j = arr.length; i < j; i++) {
if (obj[arr[i]]) {
obj[arr[i]]++;
}
}
console.log(obj['mn']);
This is what you're looking for:
var arr = [['ab','pq','mn','ab','mn','ab'],'mn','mn'];
var obj = { };
function count(arr, obj) {
for (var i = 0, j = arr.length; i < j; i++) {
if (Array.isArray(arr[i])) {
count(arr[i], obj);
}
else if (typeof obj[arr[i]] !== 'undefined') {
obj[arr[i]]++;
}
else {
obj[arr[i]] = 1;
}
}
return obj;
}
console.log(count(arr, obj));
This is a recursive implementation. When it gets to an array, the recursion get one level deeper.
You are calling obj[['ab','pq','mn','ab','mn','ab']], which is obviously not what you wanted.
You need a depth first search.
If arr[i] is an array, then you need to loop through that array.

Javascript: Simple Function - Uncaught TypeError: Cannot read property 'length' of undefined

I have a function that simply returns the longest property of a given array.
It's a for loop that assigns the looped property to a variable, with the length of the property is longer than that of the variable.
And at last it returns this new variable. But I get an error in line 10, that it can't read the length of undefined.
It seems to have a problem with someArray[i].length inside the for loop.
function longestString(i) {
// i will be an array.
// return the longest string in the array
var someArray = i;
console.log(someArray);
var longestItem = someArray[0];
console.log(longestItem);
for (i = 0; someArray.length; i++) {
if (longestItem.length < someArray[i].length) {
console.log(longestItem);
console.log(someArray[i]);
longestItem = someArray[i];
}
}
document.write(longestItem);
console.log(longestItem);
return longestItem;
}
longestString(['a', 'ab', 'abc']) // should return 'abc'
Any suggestions?
Your for-loop's condition has error.
It should be like given below.
for (i = 0; i < someArray.length; i++)
Check out this fiddle.
Here is the complete code.
function longestString(i) {
// i will be an array.
// return the longest string in the array
var someArray = i;
document.write(someArray); // just testing
var longestItem = someArray[0];
for (i = 0; i < someArray.length; i++) { //Changes in the condition
if (longestItem.length < someArray[i].length) {
longestItem = someArray[i];
}
}
document.write(longestItem);
return longestItem;
}
longestString(['a', 'ab', 'abc']) // should return 'abc'
First of all don't use the same name ifor the function parameter and then in the for loop counter, you may put yourself in really big troubles.
Second thing, your loop doesn't have a stop condition you missed i<someArray.length, it should be like this:
for (i = 0; i<someArray.length; i++) {
if (longestItem.length < someArray[i].length) {
console.log(longestItem);
console.log(someArray[i]);
longestItem = someArray[i];
}
}
Last thing use console.log() or console.dir() to debug/test instead of document.write() because it's a very very bad practice.
There are two errors on your for loop:
You are using an i function parameter which you are using again in your for loop. Try to use a different variable name inside your for loop or at least define the variable with var (to retain the scope), otherwise you will shadow the variable declared as function parameter.
The second one is that you forget to include the test condition into the loop.
function longestString(len) {
// i will be an array.
// return the longest string in the array
var someArray = len;
var longestItem = someArray[0];
var length = someArray.length;
for (var i = 0 ; i < length; i++) {
if (longestItem.length < someArray[i].length) {
longestItem = someArray[i];
}
}
console.log(longestItem);
return longestItem;
}
longestString(['a', 'ab', 'abc']) // should return 'abc'
Maybe there's more than one longest string. I'd suggest looking at the Array instance iteration methods.
var array = ['a', 'abc', 'ab', 'def'];
var maxlen = Math.max.apply(null, array.map(function(string){
return string.length;
}));
var longest = array.filter(function(string){
return string.length === maxlen;
});
var pre = document.createElement('pre');
pre.innerHTML = JSON.stringify(longest);
document.body.appendChild(pre);

Count how many strings in an array have duplicates in the same array [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Array value count javascript
I have an array which contains several duplicates, what I'm trying to achieve is to count how many duplicates each unique string has in this one array.
The array looks something like this
array = ['aa','bb','cc','aa','ss','aa','bb'];
Thus I would like to do something like this
if (xWordOccurrences >= 5) {
// do something
}
But I'm not sure how I would code this.
I was thinking, create an object with each unique string, then loop through the original array, match each string with it's object and increment it's number by 1, then loop over the object to see which words had the most duplicates...
But this seems like an over complexe way to do it.
You can use an object which has keys of the Array's values and do something like this
// count everything
function getCounts(arr) {
var i = arr.length, // var to loop over
obj = {}; // obj to store results
while (i) obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
return obj;
}
// get specific from everything
function getCount(word, arr) {
return getCounts(arr)[word] || 0;
}
getCount('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
If you only ever want to get one, then it'd be more a bit more efficient to use a modified version of getCounts which looks similar to getCount, I'll call it getCount2
function getCount2(word, arr) {
var i = arr.length, // var to loop over
j = 0; // number of hits
while (i) if (arr[--i] === word) ++j; // count occurance
return j;
}
getCount2('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
Try this function:
var countOccurrences = function(arr,value){
var len = arr.length;
var occur = 0;
for(var i=0;i<len;i++){
if(arr[i]===value){
occur++;
}
}
return occur;
}
var count = countOccurrences(['aaa','bbb','ccc','bbb','ddd'],'bbb'); //2
If you want, you can also add this function to the Array prototype:
Array.prototype.countOccurrences = function(value){
var len = this.length;
var occur = 0;
for(var i=0;i<len;i++){
if(this[i]===value){
occur++;
}
}
return occur;
}
How about you build an object with named property?
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var summary = {};
var item = '';
for ( i in array){
item = array[i];
if(summary[item]){
summary[item] += 1;
}
else{
summary[item] = 1;
}
}
console.log( summary );
summary will contain like this
{aa: 3, bb: 2, cc: 1, ss: 1}
which you could then iterate on and then sort them later on if needed.
finally to get your count, you could use this summary['aa']
<script type="text/javascript">
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var myMap = {};
for(i = 0; i < array.length; i++) {
var count = myMap[array[i]];
if(count != null) {
count++;
} else {
count = 1;
}
myMap[array[i]] = count;
}
// at this point in the script, the map now contains each unique array item and a count of its entries
</script>
Hope this solves your problem
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var dups = {};
for (var i = 0, l = array.length; i < l; i++ ) {
dups[array[i]] = [];
}
for (str in dups) {
for (var i = 0, l = array.length; i < l; i++ ) {
if (str === array[i]) {
dups[str].push(str);
}
}
}
for (str in dups) {
console.log(str + ' has ' + (dups[str].length - 1) + ' duplicate(s)');
}
This function may do everything you need.
function countDupStr(arr, specifier) {
var count = {}, total = 0;
arr.forEach(function (v) {
count[v] = (count[v] || 0) + 1;
});
if(typeof specifier !== 'undefined') {
return count[specifier] - 1;
}
Object.keys(count).forEach(function (k) {
total += count[k] - 1;
});
return total;
}
Each value in the array is assigned and incremented to the count object. Whether or not a specifier was passed, the function will return duplicates of that specific string or the total number of duplicates. Note that this particular technique will only work on string-coercible values inside your arrays, as Javascript can only index objects by string.
What this means is that during object assignment, the keys will normalize down to strings and cannot be relied upon for uniqueness. That is to say, this function wouldn't be able to discern the difference between duplicates of 3 and '3'. To give an example, if I were to perform:
var o = {}, t = {};
o[t] = 1;
console.log(o);
The key used in place of t would eventually be t.toString(), thus resulting in the perhaps surprising object of {'[object Object]': 1}. Just something to keep in mind when working with Javascript properties.
I saw this post about it, perhaps it can help:
http://ryanbosinger.com/blog/2011/javascript-count-duplicates-in-an-array/

Categories