admin管理员组

文章数量:1316023

I'm trying to build a javascript function which would count the number of occurrences of each word in an input array.

Example :

Input

a=["a","booster","booster","constructor","adam","adam","adam","adam"]

Output:

"a":1
"booster":2
"constructor":1
"adam":4

Output should be dict-alike.

I'm new to javascript and I tried to use a dict. But objects have a property called "constructor", so cnt["constructor"] seems not to work.

Here is my code and the result:

var cnt={};
console.log("constructor");

for(var i=0;i<a.length;++i)
{
    if(! (a[i] in cnt))
        cnt[a[i]]=0;
    else
        cnt[a[i]]+=1;
}

for(var item in cnt)
    console.log(item+":"+cnt[item]);

Result:

You can see that 1 is added to constructor of cnt as a string.

I'm trying to build a javascript function which would count the number of occurrences of each word in an input array.

Example :

Input

a=["a","booster","booster","constructor","adam","adam","adam","adam"]

Output:

"a":1
"booster":2
"constructor":1
"adam":4

Output should be dict-alike.

I'm new to javascript and I tried to use a dict. But objects have a property called "constructor", so cnt["constructor"] seems not to work.

Here is my code and the result:

var cnt={};
console.log("constructor");

for(var i=0;i<a.length;++i)
{
    if(! (a[i] in cnt))
        cnt[a[i]]=0;
    else
        cnt[a[i]]+=1;
}

for(var item in cnt)
    console.log(item+":"+cnt[item]);

Result:

You can see that 1 is added to constructor of cnt as a string.

Share Improve this question edited Feb 7, 2014 at 12:20 Denys Séguret 383k90 gold badges810 silver badges775 bronze badges asked Feb 7, 2014 at 11:07 BoosterBooster 1,66913 silver badges18 bronze badges 9
  • 2 Interesting question actually. Instead of blindly downvoting, try to solve the OP problem. Is it important if he tried anything or not? – dfsq Commented Feb 7, 2014 at 11:22
  • I just don't know why this question is downvoted. It seems that array can't support the same usage as map in C++ STL because the properties. – Booster Commented Feb 7, 2014 at 11:24
  • 1 @dfsq I agree with you, however, it's easier to understand the actual problem with some code provided. – user1636522 Commented Feb 7, 2014 at 11:50
  • @Pinal, I've edited my question and added my code. – Booster Commented Feb 7, 2014 at 12:33
  • 1 @Pinal. This question is already answered. Hope to see your answer if you have a better one. – Booster Commented Feb 7, 2014 at 13:11
 |  Show 4 more ments

3 Answers 3

Reset to default 13
function count(arr){
  return arr.reduce(function(m,e){
    m[e] = (+m[e]||0)+1; return m
  },{});
}

The idea behind are

  • the use of reduce for elegance
  • the conversion of m[e] to a number using +m[e] to avoid the constructor (or toString) problem

Demonstration

var arr = ['apple', 'orange', 'grape', 'apple'];
var initialValue = {};

var result = arr.reduce(function(accumulator, curr, idx, arr) {
    if (Object.hasOwnProperty.call(accumulator, curr)) {   // does current exist as key on initialValue object?
        accumulator[curr]++;
    } else {    // no key for current on initialValue object
        accumulator[curr] = 1;
    }
    return accumulator;
}, initialValue);

console.log(result);

You can also create an array just by initializing [] as the initial accumulator.

var fruits = ['apple', 'orange', 'grape', 'apple'].reduce((countFruits,currentFruit)=>{
  if(typeof countFruits[currentFruit]!=="undefined"){
    countFruits[currentFruit] = countFruits[currentFruit]+1
    return countFruits
  }
  countFruits[currentFruit] = 1
  return countFruits
},[])
console.log(fruits) 

本文标签: javascriptWord Frequency Countfix a bug with standard propertyStack Overflow