Cómo contar el valor duplicado en una matriz en javascript

100

Actualmente, tengo una matriz como esa:

var uniqueCount = Array();

Después de algunos pasos, mi matriz se ve así:

uniqueCount = [a,b,c,d,d,e,a,b,c,f,g,h,h,h,e,a];

¿Cómo puedo contar cuántos a, b, c hay en la matriz? Quiero tener un resultado como:

a = 3
b = 1
c = 2
d = 2

etc.

detno29
fuente
1
posible duplicado de stackoverflow.com/questions/12749200/…
Vinay Pratap Singh
@Nirk Supongo que musical_coder se refería a un mapa {}, no a la programación funcional map.
Matt Ball

Respuestas:

28

function count() {
    array_elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];

    array_elements.sort();

    var current = null;
    var cnt = 0;
    for (var i = 0; i < array_elements.length; i++) {
        if (array_elements[i] != current) {
            if (cnt > 0) {
                document.write(current + ' comes --> ' + cnt + ' times<br>');
            }
            current = array_elements[i];
            cnt = 1;
        } else {
            cnt++;
        }
    }
    if (cnt > 0) {
        document.write(current + ' comes --> ' + cnt + ' times');
    }

}

count();

Violín de demostración

También puede utilizar funciones de orden superior para realizar la operación. Ver esta respuesta

Vinay Pratap Singh
fuente
1
la instrucción if adicional después del ciclo es innecesaria ... solo use for (var i = 0; i <= array_elements.length; i++) {o en <=lugar de <.
EmmaGamma
Hola @Vinay, ¿quizás podrías ayudarme aquí? stackoverflow.com/questions/57819850/…
SMPLYJR
321
var counts = {};
your_array.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
SheetJS
fuente
9
Esta es definitivamente la respuesta más simple
Josh Beam
3
(cuenta [x] || 0) +1 ¿cómo está dando cuenta esto?
jsduniya
5
@SidBhalke: la expresión counts[x] || 0devuelve el valor de counts[x]si está establecido, de lo contrario 0. Luego, simplemente agregue uno y configúrelo nuevamente en el objeto y el conteo está listo.
Constantinius
1
@SheetJS si se pregunta por qué el voto negativo, fui yo; Estaba navegando en el móvil y hice clic en el botón sin darme cuenta. Una vez que me enteré, ya era demasiado tarde para revertir. Disculpas por eso, la respuesta es realmente buena. Si desea editarlo, me complacerá revertirlo.
Todor Minakov
4
También con reduce:var counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
Alberto89
70

Algo como esto:

uniqueCount = ["a","b","c","d","d","e","a","b","c","f","g","h","h","h","e","a"];
var count = {};
uniqueCount.forEach(function(i) { count[i] = (count[i]||0) + 1;});
console.log(count);

Use un bucle for simple en lugar de forEach si no desea que esto se interrumpa en los navegadores más antiguos.

loxxy
fuente
4
@web_dev crea un objeto de matriz asociativo llamado recuento que tendrá un par clave-valor para cada elemento único en la matriz, donde la clave es el valor del elemento único y el valor es el recuento. Él itera sobre la matriz y para cada valor aumenta el valor o crea el par clave-valor (el valor de la clave inexistente se evalúa como indefinido, por lo que el operador || or toma un cero y agrega el 1)
robisrob
@neelmeg Tal vez escribir todos los parámetros para "forEach" ayude a comprender mejor ("i" es el valor de cada matriz y NO su índice):uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
Pedro Ferreira
¿Cuál sería una buena manera de dar un paso más y ordenar por conteo total?
temblor
37

Me encontré con esta pregunta (muy antigua). Curiosamente, falta la solución más obvia y elegante (en mi humilde opinión): Array.prototype.reduce (...) . Todos los navegadores principales admiten esta función desde aproximadamente 2011 (IE) o incluso antes (todos los demás):

var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = arr.reduce(function(prev, cur) {
  prev[cur] = (prev[cur] || 0) + 1;
  return prev;
}, {});

// map is an associative array mapping the elements to their frequency:
document.write(JSON.stringify(map));
// prints {"a": 3, "b": 2, "c": 2, "d": 2, "e": 2, "f": 1, "g": 1, "h": 3}

isnot2bad
fuente
10

Línea única basada en la función de matriz de reducción

const uniqueCount =  ["a", "b", "c", "d", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
const distribution = uniqueCount.reduce((acum,cur) => Object.assign(acum,{[cur]: (acum[cur] | 0)+1}),{});
console.log(JSON.stringify(distribution,null,2));

dinigo
fuente
Me acabo de dar cuenta de que @ isnot2bad ( stackoverflow.com/a/32886673/621058 ) es casi lo mismo que el mío. Simplemente uso funciones y constantes de flechas gordas
dinigo
8

Lo simple es mejor, una variable, una función :)

const counts = arr.reduce((acc, value) => ({
   ...acc,
   [value]: (acc[value] || 0) + 1
}), {});
Shannon Hochkins
fuente
6

Creo que esta es la forma más sencilla de contar ocurrencias con el mismo valor en la matriz.

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

// Initial array
let array = ['a', 'b', 'c', 'd', 'd', 'e', 'a', 'b', 'c', 'f', 'g', 'h', 'h', 'h', 'e', 'a'];

// Unique array without duplicates ['a', 'b', ... , 'h']
let unique = [...new Set(array)];

// This array counts duplicates [['a', 3], ['b', 2], ... , ['h', 3]] 
let duplicates = unique.map(value => [value, array.filter(str => str === value).length]);
Erik Martín Jordán
fuente
5

Nadie que responda parece estar usando el Map()integrado para esto, que tiende a ser mi opción combinada con Array.prototype.reduce():

const data = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
const result = data.reduce((a, c) => a.set(c, (a.get(c) || 0) + 1), new Map());
console.log(...result);

Nb, tendrá que polyfillMap() si desea usarlo en navegadores más antiguos.

aendrew
fuente
¿Podrías explicar un poco en profundidad cómo está funcionando esto? (especialmente la parte set / get). Traté de dividir el reductor en una función, pero "get" no es una función en respuesta.
Antoine Nedelec
Ok gety las setfunciones provienen del Mapobjeto. Pero el acumulador inicial no es un objeto Map, entonces, ¿por qué la versión reducida del reductor toma uno?
Antoine Nedelec
@AntoineNedelec El valor inicial es un nuevo Mapobjeto; ver el segundo argumento de la reducción. Map.prototype.setdevuelve el objeto de mapa y Map.prototype.getdevuelve undefinedo el valor de cualquier clave que se le proporcione. Esto nos permite obtener el recuento actual de cada letra (o 0si no está definido), luego incrementarlo en uno, luego establecer el recuento de esa letra en el nuevo recuento, que devuelve el mapa y se convierte en el nuevo valor acumulador.
aendrew
4

Puede tener un objeto que contenga recuentos. Camine sobre la lista e incremente el recuento de cada elemento:

var counts = {};

uniqueCount.forEach(function(element) {
  counts[element] = (counts[element] || 0) + 1;
});

for (var element in counts) {
  console.log(element + ' = ' + counts[element]);
} 
nkron
fuente
¿Por qué estableciste esta condición counts[element] || 0?
AskMen
La primera vez que se accede a counts[element]devoluciones undefinedya que la propiedad aún no tiene valor. Si luego intentas agregar undefined + 1, terminarás con NaN . El (count[element] || 0)reemplazará el undefinedpor 0lo que agregar 1produce en 1lugar de NaN. ECMAScript 2020 agrega el operador de fusión nula ??que hace algo similar pero es un poco más explícito que está usando el segundo valor cuando el primero es undefined(o null). Esa versión sería (counts[element] ?? 0) + 1.
nkron
4

Puede resolverlo sin usar ningún bucle for / while ou forEach.

function myCounter(inputWords) {        
    return inputWords.reduce( (countWords, word) => {
        countWords[word] = ++countWords[word] || 1;
        return countWords;
    }, {});
}

¡Espero que te ayude!

Pablo Souza
fuente
4

// new example.
var str= [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5];

function findOdd(para) {
  var count = {};
  para.forEach(function(para) {
  count[para] = (count[para] || 0) + 1;
  });
  return count;
}

console.log(findOdd(str));

Ryan Luu
fuente
3

Puedes hacer algo como eso:

uniqueCount = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = new Object();

for(var i = 0; i < uniqueCount.length; i++) {
 if(map[uniqueCount[i]] != null) {
    map[uniqueCount[i]] += 1;
} else {
    map[uniqueCount[i]] = 1;
    }
}

ahora tienes un mapa con todos los personajes contados

Rami
fuente
1
var uniqueCount = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
// here we will collect only unique items from the array
var uniqueChars = [];

// iterate through each item of uniqueCount
for (i of uniqueCount) {
// if this is an item that was not earlier in uniqueCount, 
// put it into the uniqueChars array
  if (uniqueChars.indexOf(i) == -1) {
    uniqueChars.push(i);
  } 
}
// after iterating through all uniqueCount take each item in uniqueChars
// and compare it with each item in uniqueCount. If this uniqueChars item 
// corresponds to an item in uniqueCount, increase letterAccumulator by one.
for (x of uniqueChars) {
  let letterAccumulator = 0;
  for (i of uniqueCount) {
    if (i == x) {letterAccumulator++;}
  }
  console.log(`${x} = ${letterAccumulator}`);
}
Ilya Kushlianski
fuente
Gracias por actualizarlo, mucho más útil para los principiantes.
Regular Joe
1

Duplica en una matriz que contiene alfabetos:

var arr = ["a", "b", "a", "z", "e", "a", "b", "f", "d", "f"],
  sortedArr = [],
  count = 1;

sortedArr = arr.sort();

for (var i = 0; i < sortedArr.length; i = i + count) {
  count = 1;
  for (var j = i + 1; j < sortedArr.length; j++) {
    if (sortedArr[i] === sortedArr[j])
      count++;
  }
  document.write(sortedArr[i] + " = " + count + "<br>");
}

Duplica en una matriz que contiene números:

var arr = [2, 1, 3, 2, 8, 9, 1, 3, 1, 1, 1, 2, 24, 25, 67, 10, 54, 2, 1, 9, 8, 1],
  sortedArr = [],
  count = 1;
sortedArr = arr.sort(function(a, b) {
  return a - b
});
for (var i = 0; i < sortedArr.length; i = i + count) {
  count = 1;
  for (var j = i + 1; j < sortedArr.length; j++) {
    if (sortedArr[i] === sortedArr[j])
      count++;
  }
  document.write(sortedArr[i] + " = " + count + "<br>");
}

Ankit Gupta
fuente
1

var testArray = ['a', 'b', 'c', 'd', 'd', 'e', ​​'a', 'b', 'c', 'f', 'g', 'h ',' h ',' h ',' e ',' a '];

var newArr = [];
testArray.forEach((item) => {
    newArr[item] = testArray.filter((el) => {
            return el === item;
    }).length;
})
console.log(newArr);
usuario6160741
fuente
1
uniqueCount = ["a","b","a","c","b","a","d","b","c","f","g","h","h","h","e","a"];
var count = {};
uniqueCount.forEach((i) => { count[i] = ++count[i]|| 1});
console.log(count);
Muhammad Javeed
fuente
1

sheet.js simplificado answare

var counts = {};
var aarr=['a','b','a'];
aarr.forEach(x=>counts[x]=(counts[x] || 0)+1 );
console.log(counts)

ßãlãjî
fuente
0

Una combinación de buenas respuestas:

var count = {};
var arr = ['a', 'b', 'c', 'd', 'd', 'e', 'a', 'b', 'c', 'f', 'g', 'h', 'h', 'h', 'e', 'a'];
var iterator = function (element) {
    count[element] = (count[element] || 0) + 1;
}

if (arr.forEach) {
    arr.forEach(function (element) {
        iterator(element);
    });
} else {
    for (var i = 0; i < arr.length; i++) {
        iterator(arr[i]);
    }
}  

Espero que sea de ayuda.

Xiaodan Mao
fuente
0
public class CalculateCount {
public static void main(String[] args) {
    int a[] = {1,2,1,1,5,4,3,2,2,1,4,4,5,3,4,5,4};
    Arrays.sort(a);
    int count=1;
    int i;
    for(i=0;i<a.length-1;i++){
        if(a[i]!=a[i+1]){
            System.out.println("The Number "+a[i]+" appears "+count+" times");
            count=1;                
        }
        else{
            count++;
        }
    }
    System.out.println("The Number "+a[i]+" appears "+count+" times");

}   

}

Parv Johari
fuente
¿Puedes agregar algo de contexto a esto?
Neo
0

Al usar array.map podemos reducir el ciclo, vea esto en jsfiddle

function Check(){
    var arr = Array.prototype.slice.call(arguments);
    var result = [];
    for(i=0; i< arr.length; i++){
        var duplicate = 0;
        var val = arr[i];
        arr.map(function(x){
            if(val === x) duplicate++;
        })
        result.push(duplicate>= 2);
    }
    return result;
}

Probar:

var test = new Check(1,2,1,4,1);
console.log(test);
Ali Adravi
fuente
0

var string = ['a','a','b','c','c','c','c','c','a','a','a'];

function stringCompress(string){

var obj = {},str = "";
string.forEach(function(i) { 
  obj[i] = (obj[i]||0) + 1;
});

for(var key in obj){
  str += (key+obj[key]);
}
  console.log(obj);
  console.log(str);
}stringCompress(string)

/*
Always open to improvement ,please share 
*/

sg28
fuente
0

Cree un archivo, por ejemplo, demo.jsy ejecútelo en la consola con el nodo demo.jsy obtendrá la aparición de elementos en forma de matriz.

var multipleDuplicateArr = Array(10).fill(0).map(()=>{return Math.floor(Math.random() * Math.floor(9))});
console.log(multipleDuplicateArr);

var resultArr = Array(Array('KEYS','OCCURRENCE'));

for (var i = 0; i < multipleDuplicateArr.length; i++) {
  var flag = true;
  for (var j = 0; j < resultArr.length; j++) {
     if(resultArr[j][0] == multipleDuplicateArr[i]){
       resultArr[j][1] = resultArr[j][1] + 1;
       flag = false;
      }
  }
  if(flag){
    resultArr.push(Array(multipleDuplicateArr[i],1));
  }
}

console.log(resultArr);

Obtendrá el resultado en la consola de la siguiente manera:

[ 1, 4, 5, 2, 6, 8, 7, 5, 0, 5 ] . // multipleDuplicateArr
[ [ 'KEYS', 'OCCURENCE' ],        // resultArr
  [ 1, 1 ],
  [ 4, 1 ],
  [ 5, 3 ],
  [ 2, 1 ],
  [ 6, 1 ],
  [ 8, 1 ],
  [ 7, 1 ],
  [ 0, 1 ] ]
Jitendra
fuente
0

La manera mas rapida:

La complejidad computacional es O (n).

function howMuchIsRepeated_es5(arr) {
	const count = {};
	for (let i = 0; i < arr.length; i++) {
		const val = arr[i];
		if (val in count) {
			count[val] = count[val] + 1;
		} else {
			count[val] = 1;
		}
	}

	for (let key in count) {
		console.log("Value " + key + " is repeated " + count[key] + " times");
	}
}

howMuchIsRepeated_es5(['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a']);

El código más corto:

Utilice ES6.

function howMuchIsRepeated_es6(arr) {
	// count is [ [valX, count], [valY, count], [valZ, count]... ];
	const count = [...new Set(arr)].map(val => [val, arr.join("").split(val).length - 1]);

	for (let i = 0; i < count.length; i++) {
		console.log(`Value ${count[i][0]} is repeated ${count[i][1]} times`);
	}
}

howMuchIsRepeated_es6(['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a']);

Serhii Zghama
fuente
0
var arr = ['a','d','r','a','a','f','d'];  

//call function and pass your array, function will return an object with array values as keys and their count as the key values.
duplicatesArr(arr);

function duplicatesArr(arr){
    var obj = {}
    for(var i = 0; i < arr.length; i++){
        obj[arr[i]] = [];
        for(var x = 0; x < arr.length; x++){
            (arr[i] == arr[x]) ? obj[arr[i]].push(x) : '';
        }
        obj[arr[i]] = obj[arr[i]].length;
    }

    console.log(obj);
    return obj;
}
gritos
fuente
0

Declare un objeto arrpara contener el conjunto único como claves. Rellenar arrpor bucle a través de la matriz de una vez usando el mapa. Si la clave no se ha encontrado previamente, agregue la clave y asigne un valor de cero. En cada iteración, incremente el valor de la clave.

Dado testArray:

var testArray = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];

solución:

var arr = {};
testArray.map(x=>{ if(typeof(arr[x])=="undefined") arr[x]=0; arr[x]++;});

JSON.stringify(arr) saldrá

{"a":3,"b":2,"c":2,"d":2,"e":2,"f":1,"g":1,"h":3}

Object.keys(arr) volverá ["a","b","c","d","e","f","g","h"]

Para encontrar las apariciones de cualquier elemento, por ejemplo, b arr['b']generará2

jidexl21
fuente
No publique solo el código como respuesta, sino que también incluya una explicación de lo que hace su código y cómo resuelve el problema. Las respuestas con una explicación son generalmente de mayor calidad y es más probable que atraigan votos positivos.
Mark Rotteveel
0

Es simple en javascript usando el método de reducción de matriz:

const arr = ['a','d','r','a','a','f','d'];
const result =  arr.reduce((json,val)=>({...json, [val]:(json[val] | 0) + 1}),{});
console.log(result)
//{ a:3,d:2,r:1,f:1 }

Yathin K Rao
fuente
0

Uso:

wrap.common.getUniqueDataCount(, columnName);

CÓDIGO:

function getUniqueDataCount(objArr, propName) {
        var data = [];
        objArr.forEach(function (d, index) {
            if (d[propName]) {
                data.push(d[propName]);
            }
        });

        var uniqueList = [...new Set(data)];

        var dataSet = {};
        for (var i=0; i < uniqueList.length; i++) {
            dataSet[uniqueList[i]] = data.filter(x => x == uniqueList[i]).length;
        }
        
        return dataSet;
    }

Retazo

var data= [
          {a:'you',b:'b',c:'c',d:'c'},
          {a: 'you', b: 'b', c: 'c', d:'c'},
          {a: 'them', b: 'b', c: 'c', d:'c'},
          {a: 'them', b: 'b', c: 'c', d:'c'},
          {a: 'okay', b: 'b', c: 'c', d:'c'},
          {a: 'okay', b: 'b', c: 'c', d:'c'},
          ];
          
  console.log(getUniqueDataCount(data, 'a'));       
  
  function getUniqueDataCount(objArr, propName) {
        var data = [];
        objArr.forEach(function (d, index) {
            if (d[propName]) {
                data.push(d[propName]);
            }
        });

        var uniqueList = [...new Set(data)];

        var dataSet = {};
        for (var i=0; i < uniqueList.length; i++) {
            dataSet[uniqueList[i]] = data.filter(x => x == uniqueList[i]).length;
        }

        return dataSet;
    }

ARr0w
fuente