recorrer objetos objeto matriz eliminar elementos elemento ejemplos buscar array agregar javascript arrays count element

objetos - matriz javascript



Contando las ocurrencias/frecuencia de los elementos de la matriz (25)

En Javascript, intento tomar una matriz inicial de valores numéricos y contar los elementos que contiene. Idealmente, el resultado sería dos nuevas matrices, la primera especificando cada elemento único, y la segunda que contiene el número de veces que ocurre cada elemento. Sin embargo, estoy abierto a sugerencias sobre el formato de la salida.

Por ejemplo, si la matriz inicial fue:

5, 5, 5, 2, 2, 2, 2, 2, 9, 4

Entonces se crearían dos nuevas matrices. El primero contendría el nombre de cada elemento único:

5, 2, 9, 4

El segundo contendría la cantidad de veces que ese elemento ocurrió en la matriz inicial:

3, 5, 1, 1

Debido a que el número 5 ocurre tres veces en el conjunto inicial, el número 2 ocurre cinco veces y el 9 y el 4 aparecen una vez.

He buscado mucho para encontrar una solución, pero nada parece funcionar, y todo lo que he probado ha terminado siendo ridículamente complejo. ¡Cualquier ayuda sería apreciada!

Gracias :)


¿Qué tal una opción de ECMAScript2015?

const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; const aCount = new Map([...new Set(a)].map( x => [x, a.filter(y => y === x).length] ));

aCount.get(5) // 3 aCount.get(2) // 5 aCount.get(9) // 1 aCount.get(4) // 1

Este ejemplo pasa la matriz de entrada al constructor de Set creando una colección de valores únicos . La sintaxis extendida expande estos valores en una nueva matriz para que podamos llamar a map y traducir esto en una matriz bidimensional de pares [value, count] , es decir, la siguiente estructura:

Array [ [5, 3], [2, 5], [9, 1], [4, 1] ]

La nueva matriz se pasa al constructor del Map da como resultado un objeto iterable :

Map { 5 => 3, 2 => 5, 9 => 1, 4 => 1 }

Lo mejor de un objeto Map es que conserva los tipos de datos, es decir, aCount.get(5) devolverá 3 pero aCount.get("5") devolverá undefined . También permite que cualquier valor / tipo actúe como clave, lo que significa que esta solución también funcionará con una matriz de objetos.

function frequencies(/* {Array} */ a){ return new Map([...new Set(a)].map( x => [x, a.filter(y => y === x).length] )); } let foo = { value: ''foo'' }, bar = { value: ''bar'' }, baz = { value: ''baz'' }; let aNumbers = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4], aObjects = [foo, bar, foo, foo, baz, bar]; frequencies(aNumbers).forEach((val, key) => console.log(key + '': '' + val)); frequencies(aObjects).forEach((val, key) => console.log(key.value + '': '' + val));


Aquí hay algo ligero y fácil para los ojos ...

function count(a,i){ var result = 0; for(var o in a) if(a[o] == i) result++; return result; }

Editar: Y como quieres todas las ocurrencias ...

function count(a){ var result = {}; for(var i in a){ if(result[a[i]] == undefined) result[a[i]] = 0; result[a[i]]++; } return result; }


Aquí hay un método clásico de la vieja escuela para contar matrices.

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; var counted = [], count = []; var i = 0, j = 0, k = 0; while (k < arr.length) { if (counted.indexOf(arr[k]) < 0) { counted[i] = arr[k]; count[i] = 0; for (j = 0; j < arr.length; j++) { if (counted[i] == arr[j]) { count[i]++; } } i++; } else { k++; } }

Puede ordenarlo primero si desea un resultado alfabético, pero si desea conservar el orden en que se ingresaron los datos, pruébelo. Los bucles anidados pueden ser un poco más lentos que algunos de los otros métodos en esta página.


Aquí hay una manera de contar las ocurrencias dentro de una matriz de objetos. También coloca los contenidos de la primera matriz dentro de una nueva matriz para ordenar los valores de modo que no se interrumpa el orden en la matriz original. Luego, se usa una función recursiva para recorrer cada elemento y contar la cantidad de propiedades de cada objeto dentro de la matriz.

var big_array = [ { name: "Pineapples", quantity: 3 }, { name: "Pineapples", quantity: 1 }, { name: "Bananas", quantity: 1 }, { name: "Limes", quantity: 1 }, { name: "Bananas", quantity: 1 }, { name: "Pineapples", quantity: 2 }, { name: "Pineapples", quantity: 1 }, { name: "Bananas", quantity: 1 }, { name: "Bananas", quantity: 1 }, { name: "Bananas", quantity: 5 }, { name: "Coconuts", quantity: 1 }, { name: "Lemons", quantity: 2 }, { name: "Oranges", quantity: 1 }, { name: "Lemons", quantity: 1 }, { name: "Limes", quantity: 1 }, { name: "Grapefruit", quantity: 1 }, { name: "Coconuts", quantity: 5 }, { name: "Oranges", quantity: 6 } ]; function countThem() { var names_array = []; for (var i = 0; i < big_array.length; i++) { names_array.push( Object.assign({}, big_array[i]) ); } function outerHolder(item_array) { if (item_array.length > 0) { var occurrences = []; var counter = 0; var bgarlen = item_array.length; item_array.sort(function(a, b) { return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0); }); function recursiveCounter() { occurrences.push(item_array[0]); item_array.splice(0, 1); var last_occurrence_element = occurrences.length - 1; var last_occurrence_entry = occurrences[last_occurrence_element].name; var occur_counter = 0; var quantity_counter = 0; for (var i = 0; i < occurrences.length; i++) { if (occurrences[i].name === last_occurrence_entry) { occur_counter = occur_counter + 1; if (occur_counter === 1) { quantity_counter = occurrences[i].quantity; } else { quantity_counter = quantity_counter + occurrences[i].quantity; } } } if (occur_counter > 1) { var current_match = occurrences.length - 2; occurrences[current_match].quantity = quantity_counter; occurrences.splice(last_occurrence_element, 1); } counter = counter + 1; if (counter < bgarlen) { recursiveCounter(); } } recursiveCounter(); return occurrences; } } alert(JSON.stringify(outerHolder(names_array))); }


Aqui tienes:

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]; }

Demostración en vivo: http://jsfiddle.net/simevidas/bnACW/


Creo que esta es la manera más simple de contar las ocurrencias con el mismo valor en el conjunto.

var a = [true, false, false, false]; a.filter(function(value){ return value === false; }).length


Dado matriz x ie x = [''boy'',''man'',''oldman'',''scout'',''pilot'']; número de apariciones de un elemento ''man'' es

x.length - x.toString().split('',man,'').toString().split('','').length ;


En cuanto a mi comentario, le pregunté a @Emissary sobre un ajuste en su solución. Estoy agregando la forma en que lo manejé:

let distinctArr = yourArray.filter((curElement, index, array) => array.findIndex(t => t.prop1=== curElement.prop1 && t.prop2 === curElement.prop2 && t.prop3=== curElement.prop3) === index); let distinctWithCount = [...new Set(distinctArr)].map(function(element){element.prop4 = yourArray.filter(t => t.prop1=== element.prop1 && t.prop2 === element.prop2 && t.prop2=== element.prop2).length;

Lo que estoy haciendo aquí es, primero eliminar los duplicados y guardar la matriz (distinctArr) y luego contar la matriz original (yourArray) la cantidad de tiempo que se duplicó el objeto y agregar una cuarta propiedad con el valor de las ocurrencias

Espero que ayude a alguien que necesita esta solución específica Ofc está hecha con ES6


Estaba resolviendo un problema similar en Codewars y diseñé la siguiente solución que funcionó para mí.

Esto da el recuento más alto de un entero en una matriz y también el entero en sí. Creo que también se puede aplicar a la matriz de cadenas.

Para ordenar correctamente cadenas, elimine la function(a, b){return ab} del interior de la porción sort()

function mostFrequentItemCount(collection) { collection.sort(function(a, b){return a-b}); var i=0; var ans=[]; var int_ans=[]; while(i<collection.length) { if(collection[i]===collection[i+1]) { int_ans.push(collection[i]); } else { int_ans.push(collection[i]); ans.push(int_ans); int_ans=[]; } i++; } var high_count=0; var high_ans; i=0; while(i<ans.length) { if(ans[i].length>high_count) { high_count=ans[i].length; high_ans=ans[i][0]; } i++; } return high_ans; }


Hay una manera mucho mejor y más fácil de hacerlo con ramda.js . Muestra de código aquí

const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary) const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary) countBy la documentación se encuentra en la documentation


La versión ES6 debería ser mucho simplificadora (otra solución de una línea)

let arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; let acc = arr.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map()); console.log(acc); // output: Map { 5 => 3, 2 => 5, 9 => 1, 4 => 1 }

Un mapa en lugar de un objeto simple que nos ayuda a distinguir diferentes tipos de elementos, o de lo contrario todo el conteo se basa en cadenas


Mira el código a continuación.

<html> <head> <script> // array with values var ar = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; var Unique = []; // we''ll store a list of unique values in here var Counts = []; // we''ll store the number of occurances in here for(var i in ar) { var Index = ar[i]; Unique[Index] = ar[i]; if(typeof(Counts[Index])==''undefined'') Counts[Index]=1; else Counts[Index]++; } // remove empty items Unique = Unique.filter(function(){ return true}); Counts = Counts.filter(function(){ return true}); alert(ar.join('','')); alert(Unique.join('','')); alert(Counts.join('','')); var a=[]; for(var i=0; i<Unique.length; i++) { a.push(Unique[i] + '':'' + Counts[i] + ''x''); } alert(a.join('', '')); </script> </head> <body> </body> </html>


No use dos matrices para el resultado, use un objeto:

a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; result = { }; for(var i = 0; i < a.length; ++i) { if(!result[a[i]]) result[a[i]] = 0; ++result[a[i]]; }

Entonces el result se verá así:

{ 2: 5, 4: 1, 5: 3, 9: 1 }


Prueba esto:

Array.prototype.getItemCount = function(item) { var counts = {}; for(var i = 0; i< this.length; i++) { var num = this[i]; counts[num] = counts[num] ? counts[num]+1 : 1; } return counts[item] || 0; }


Puede extender el prototipo de Array, así:

Array.prototype.frequencies = function() { var l = this.length, result = {all:[]}; while (l--){ result[this[l]] = result[this[l]] ? ++result[this[l]] : 1; } // all pairs (label, frequencies) to an array of arrays(2) for (var l in result){ if (result.hasOwnProperty(l) && l !== ''all''){ result.all.push([ l,result[l] ]); } } return result; }; var freqs = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].frequencies(); alert(freqs[2]); //=> 5 // or var freqs = ''1,1,2,one,one,2,2,22,three,four,five,three,three,five'' .split('','') .frequencies(); alert(freqs.three); //=> 3

Alternativamente, puede utilizar Array.map :

Array.prototype.frequencies = function () { var freqs = {sum: 0}; this.map( function (a){ if (!(a in this)) { this[a] = 1; } else { this[a] += 1; } this.sum += 1; return a; }, freqs ); return freqs; }


Puede hacer esto mucho más fácil extendiendo sus matrices con una función de count . Funciona un poco como Array#count Rails, si estás familiarizado con él.

Array.prototype.count = function(obj){ var count = this.length; if(typeof(obj) !== "undefined"){ var array = this.slice(0), count = 0; // clone array and reset count for(i = 0; i < array.length; i++){ if(array[i] == obj){ count++; } } } return count; }

Uso:

var array = [''a'', ''a'', ''b'', ''c'']; array.count(''a''); // => 2 array.count(''b''); // => 1 array.count(''d''); // => 0 array.count(); // => 4

Fuente (esencia)


Puedes usar un objeto para mantener los resultados:

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; var counts = {}; for (var i = 0; i < arr.length; i++) { var num = arr[i]; counts[num] = counts[num] ? counts[num] + 1 : 1; } console.log(counts[5], counts[2], counts[9], counts[4]);

Entonces, ahora su objeto de recuento le puede decir cuál es el conteo de un número en particular:

console.log(counts[5]); // logs ''3''

Si desea obtener una matriz de miembros, solo use las funciones de keys()

keys(counts); // returns ["5", "2", "9", "4"]


Según la answer de y pmandell (que pmandell ), en ES6 puedes hacerlo en una sola línea :

  • Edición de 2017 : uso || para reducir el tamaño del código y hacerlo más legible.

var a=[7,1,7,2,2,7,3,3,3,7,,7,7,7]; alert(JSON.stringify( a.reduce((r,k)=>{r[k]=1+r[k]||1;return r},{}) ));

Se puede usar para contar personajes :

var s="ABRACADABRA"; alert(JSON.stringify( s.split('''').reduce((a, c)=>{a[c]++?0:a[c]=1;return a},{}) ));


Si está utilizando un guión bajo puede ir por la ruta funcional

a = [''foo'', ''foo'', ''bar'']; var results = _.reduce(a,function(counts,key){ counts[key]++; return counts }, _.object( _.map( _.uniq(a), function(key) { return [key, 0] })))

entonces tu primer arreglo es

_.keys(results)

y la segunda matriz es

_.values(results)

la mayor parte de esto se ajustará a las funciones nativas de JavaScript si están disponibles

demo: http://jsfiddle.net/dAaUU/


Si favorece un solo trazador de líneas.

arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});

Editar (12/06/2015) : La explicación de adentro hacia afuera. countMap es un mapa que mapea una palabra con su frecuencia, que podemos ver la función anónima. Lo que reduce does es aplicar la función con argumentos como todos los elementos de la matriz y countMap pasando como el valor de retorno de la última llamada a la función. El último parámetro ({}) es el valor predeterminado de countMap para la primera llamada de función.


Si usa subrayado o lodash, esto es lo más simple de hacer:

_.countBy(array);

Tal que:

_.countBy([5, 5, 5, 2, 2, 2, 2, 2, 9, 4]) => Object {2: 5, 4: 1, 5: 3, 9: 1}

Como señalaron otros, puede ejecutar las _.keys() y _.values() en el resultado para obtener solo los números únicos y sus ocurrencias, respectivamente. Pero en mi experiencia, el objeto original es mucho más fácil de tratar.


Solución ES6 con reducir (fijo):

const arr = [2, 2, 2, 3, 2] const count = arr.reduce((pre, cur) => (cur === 2) ? ++pre : pre, 0) console.log(count) // 4


const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4] function count(arr) { return arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {}) } console.log(count(data))


var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) { if (typeof acc[curr] == ''undefined'') { acc[curr] = 1; } else { acc[curr] += 1; } return acc; }, {}); // a == {2: 5, 4: 1, 5: 3, 9: 1}


var array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; function countDuplicates(obj, num){ obj[num] = (++obj[num] || 1); return obj; } var answer = array.reduce(countDuplicates, {}); // answer => {2:5, 4:1, 5:3, 9:1};

Si aún quieres dos matrices, entonces podrías usar una respuesta como esta ...

var uniqueNums = Object.keys(answer); // uniqueNums => ["2", "4", "5", "9"]; var countOfNums = Object.keys(answer).map(key => answer[key]); // countOfNums => [5, 1, 3, 1];

O si quiere que los números únicos sean números

var uniqueNums = Object.keys(answer).map(key => +key); // uniqueNums => [2, 4, 5, 9];