Как получить количество элементов в массиве, когда элементы неизвестны
Итак, я пытаюсь выяснить, как создать ассоциативный массив, в котором перечислены элементы массива, и количество раз, когда происходит каждый элемент, не зная, какие элементы заранее.
В качестве примера предположим, что у меня есть массив животных: 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
содержит запись животного и увеличивает или инициализирует значение.