Как получить количество элементов в массиве, когда элементы неизвестны

Итак, я пытаюсь выяснить, как создать ассоциативный массив, в котором перечислены элементы массива, и количество раз, когда происходит каждый элемент, не зная, какие элементы заранее.

В качестве примера предположим, что у меня есть массив животных: var animals = ['Rhino', 'Lion', 'Dog', 'Parrot', 'Parrot', 'Cat', 'Zebra', 'Rhino']

Я хотел бы сгенерировать объект, который в конечном итоге выглядит следующим образом:

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

Если бы я знал, что животные в массиве были заранее, я мог бы, конечно, сделать что-то вроде:

var animalsCount = {};

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

animalsCount['Rhino'] = numberOfRhinos

чтобы получить объект, как хотелось бы. Проблема, конечно, в том, что это становится довольно продолжительным и повторяющимся в зависимости от количества животных. Кроме того, если я не знаю, что такое тип каждого животного, я не могу создать объект таким образом. Должен быть способ сделать это, не зная этой информации, но я застрял.

Ответы

Ответ 1

Самый простой способ - создать карту, инициализируя (до 1) значения в массиве как свойство на этой карте. Вы можете увеличивать значение свойства каждый раз, когда вы видите свойство, которое не является 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
    */

Ответ 2

Просто сгенерируйте словарь, зациклив на животных, а затем залейте его петлями через своих животных снова.

    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))

Ответ 3

Просто сверните элементы массива со свойствами и сохраните их в объекте.

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

Ответ 4

Вы можете выполнять итерацию по каждому элементу в массиве, создавать ключ в объекте подсчета (ассоциативные массивы называются только что вызванными объектами в JS), если один из них не существует и установлен в 1, или если он существует, добавьте в значение.

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

  count = animalsCount[animal];

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

Ответ 5

Вы можете легко получить его в двух массивах, как показано ниже.

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));

Ответ 6

countBy в underscore может соответствовать вашим требованиям.

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

выход:

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

Ответ 7

Вы можете использовать библиотеку, например lodash, чтобы получить этот результат.

В противном случае вы можете перебирать массив. Убедитесь, что ваш прототип animalsCount содержит запись животного и увеличивает или инициализирует значение.