简体   繁体   中英

How to get count of elements in an array, when elements are unknown

So I'm trying to figure out how to generate an associative array that lists the elements of an array, and the number of times each element occurs, without knowing what the elements are beforehand.

As an example, let's say I have an array of animals: var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot', 'Cat', 'Zebra', 'Rhino']

I'd like to generate an object that ultimately looks like:

{ 'Rhino': 2, 'Lion': 1, 'Dog': 1, 'Parrot': 2, 'Cat': 1, 'Zebra': 1 }

If I knew what the animals in the array were beforehand, I could of course do something like:

var animalsCount = {};

var numberOfRhinos = animals.filter(function(animal) {
   return animal == 'Rhino'
}).length;

animalsCount['Rhino'] = numberOfRhinos

to get an object like I'd like. The problem of course is that this becomes quite lengthy and repetitive depending on the number of animals. As well, if I don't know what each type of animal is I can't create the object this way. There must be a way to do this without knowing that information, but I'm stuck.

Easiest way is to create a map, initializing (to 1) values in the array as aa property on that map. You can increment a property's value every time you see a property that is not undefined.

  function countObjs(arr) { // So the object doesn't inherit from Object.prototype and avoids property // name collisions var obj = Object.create(null); arr.forEach(function(item) { if (obj[item]) { obj[item]++; } else { obj[item] = 1; } }); return obj; } var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot', 'Cat', 'Zebra', 'Rhino']; console.log(countObjs(animals)); /* Cat: 1 Dog: 1 Lion: 1 Parrot: 2 Rhino: 2 Zebra: 1 */ 

Just generate a dictionary by looping trough the animals, then fill it looping through your animals again.

  var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot', 'Cat', 'Zebra', 'Rhino']; var animals_dict={}; for(var i=0;i<animals.length;i++){ animals_dict[animals[i]]=0; } for(var i=0;i<animals.length;i++){ animals_dict[animals[i]]=animals_dict[animals[i]]+1; } alert(JSON.stringify(animals_dict)) 

Just loop over the array elements with properties and store them in the object.

var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot','Cat', 'Zebra', 'Rhino'];
var animalsCount = {};

for(var i = animals.length - 1; i >=0; i--) {
    var count = animalsCount[animals[i]];
   if(!count) count = 1;
   else count++; 
   animalsCount[animals[i]] = count;
}

console.log(animalsCount); 
//Outupt {Rhino: 2, Zebra: 1, Cat: 1, Parrot: 2, Dog: 1…}

//accessing particular animal count
animalsCount['Cat'];                 //outputs 1

You can iterate over each element in the array, create a key in the counting object (associative arrays are called just called objects in JS) if one does not exists and set it to 1, or if it does exists add to the value.

animals.forEach(function(animal){
  var count;

  count = animalsCount[animal];

  if (count){
    animalsCount[animal] = count + 1;
  } else {
    animalsCount[animal] = 1;
  }  
})

You can easily get it in two arrays as below.

 var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot', 'Cat', 'Zebra', 'Rhino']; function foo(arr) { var a = [], b = [], prev; arr.sort(); for (var i = 0; i < arr.length; i++) { if (arr[i] !== prev) { a.push(arr[i]); b.push(1); } else { b[b.length - 1]++; } prev = arr[i]; } return [a, b]; } console.log(foo(animals)); 

Disclaimer : output array is alphabetically sorted.

The countBy in the underscore may meet your requirement.

_.countBy(animals, function(n) { return n; })

output:

{ 'Rhino': 2, 'Lion': 1, 'Dog': 1, 'Parrot': 2, 'Cat': 1, 'Zebra': 1 }

You can use library like lodash to get this result.

Otherwise you can iterate your array. Check if your animalsCount prototype contains the animal entry and increment or initialize value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM