Come contare il valore duplicato in un array in javascript


98

Attualmente, ho un array del genere:

var uniqueCount = Array();

Dopo alcuni passaggi, il mio array appare così:

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

Come posso contare quanti a, b, c ci sono nell'array? Voglio ottenere un risultato come:

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

eccetera.



@ Nirk Presumo che musical_coder significasse una mappa come in {}, non una programmazione funzionale map.
Matt Ball

Risposte:


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

Demo Fiddle

È possibile utilizzare anche funzioni di ordine superiore per eseguire l'operazione. Vedi questa risposta


1
l'istruzione if extra dopo il ciclo non è necessaria ... basta usare for (var i = 0; i <= array_elements.length; i++) {o <=invece di <.
EmmaGamma

Ciao @Vinay, forse potresti aiutarmi qui? stackoverflow.com/questions/57819850/...
SMPLYJR

320
var counts = {};
your_array.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });

9
Questa è sicuramente la risposta più semplice
Josh Beam

3
(counts [x] || 0) +1 come sta dando il conteggio?
jsduniya

5
@SidBhalke: l'espressione counts[x] || 0restituisce il valore di counts[x]se è impostata, altrimenti 0. Quindi aggiungine uno e impostalo di nuovo nell'oggetto e il conteggio è fatto.
Costantino

1
@SheetJS se ti stai chiedendo perché il voto negativo - sono stato io; Stavo navigando su un dispositivo mobile e ho fatto clic sul pulsante senza accorgermene. Una volta scoperto che era troppo tardi per tornare indietro. Mi scuso per questo, la risposta è davvero buona. Se vuoi modificarlo, sarei lieto di annullare.
Todor Minakov

4
Anche con reduce:var counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
Alberto89

70

Qualcosa come questo:

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

Usa un semplice ciclo for invece di forEach se non vuoi che questo si interrompa nei browser meno recenti.


4
@web_dev crea un oggetto array associativo chiamato count che avrà una coppia di valori chiave per ogni elemento univoco dell'array, dove la chiave è il valore dell'elemento univoco e il valore è il conteggio. Esegue l'iterazione sull'array e per ogni valore incrementa il valore o crea la coppia chiave-valore (il valore della chiave inesistente
restituisce

@neelmeg Forse scrivere tutti i parametri per "forEach" aiuta a capire meglio ("i" è ogni valore di array e NON è índex):uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
Pedro Ferreira

37

Mi sono imbattuto in questa domanda (molto vecchia). È interessante notare che manca la soluzione più ovvia ed elegante (imho): Array.prototype.reduce (...) . Tutti i principali browser supportano questa funzione dal 2011 circa (IE) o anche prima (tutti gli altri):

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}


10

Riga singola basata sulla funzione di riduzione dell'array

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


Ho appena realizzato che @ isnot2bad ( stackoverflow.com/a/32886673/621058 ) è quasi uguale al mio. Mi è capitato di usare le funzioni e le costanti della freccia grassa
dinigo

8

Semplice è meglio, una variabile, una funzione :)

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

6

Penso che questo sia il modo più semplice per contare le occorrenze con lo stesso valore nell'array.

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

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

5

Nessuno che risponde sembra utilizzare il Map()built-in per questo, che tende ad essere il mio go-to combinato 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, dovrai eseguire il polyfillMap() se desideri utilizzarlo nei browser meno recenti.


Potresti spiegare un po 'in profondità come funziona? (specialmente il set / get part). Ho provato a rompere il riduttore in una funzione ma ho "get" non è una funzione in risposta.
Antoine Nedelec

Ok gete le setfunzioni provengono Mapdall'oggetto. Ma l'accumulatore iniziale non è un oggetto Map, quindi perché la versione ridotta del riduttore ne prende uno?
Antoine Nedelec

@AntoineNedelec Il valore iniziale è un nuovo Mapoggetto; vedere il secondo argomento della riduzione. Map.prototype.setrestituisce l'oggetto mappa e Map.prototype.getrestituisce undefinedo il valore di qualsiasi chiave gli venga fornita. Questo ci consente di ottenere il conteggio corrente di ogni lettera (o 0se non definito), quindi incrementarlo di uno, quindi impostare il conteggio di quella lettera sul nuovo conteggio, che restituisce la mappa e diventa il nuovo valore dell'accumulatore.
aendrew

4

Puoi avere un oggetto che contiene conteggi. Scorri l'elenco e incrementa il conteggio per ogni elemento:

var counts = {};

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

for (var element in counts) {
  console.log(element + ' = ' + counts[element]);
} 

perché hai impostato questa condizione counts[element] || 0?
AskMen

4

Puoi risolverlo senza usare alcun ciclo for / while o forEach.

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

Spero ti aiuti!


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


3

Puoi fare qualcosa del genere:

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

ora hai una mappa con tutti i caratteri contati


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

Grazie per l'aggiornamento, molto più utile per chi inizia.
Regular Joe

1

Duplica in una matrice contenente alfabeti:

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 in una matrice contenente numeri:

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


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

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

1

answare sheet.js semplificato

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


0

Una combinazione di buone risposte:

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

Spero sia utile.


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

}   

}


Puoi aggiungere un contesto intorno a questo?
Neo

0

Usando array.map possiamo ridurre il ciclo, vedi questo su 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;
}

Testare:

var test = new Check(1,2,1,4,1);
console.log(test);

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 
*/


0

Crea un file ad esempio demo.jsed eseguilo nella console con nodo demo.jse otterrai l'occorrenza di elementi sotto forma di matrice.

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

Otterrai il risultato nella console come di seguito:

[ 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 ] ]

0

Modo più veloce:

La complessità computazionale è 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']);

Il codice più breve:

Usa 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']);


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

0

Dichiara che un oggetto arrcontiene l'insieme univoco come chiavi. Popolare arreseguendo un ciclo attraverso l'array una volta usando map. Se la chiave non è stata trovata in precedenza, aggiungere la chiave e assegnare un valore pari a zero. Ad ogni iterazione incrementa il valore della chiave.

Dato testArray:

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

soluzione:

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

JSON.stringify(arr) verrà prodotto

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

Object.keys(arr) sarà di ritorno ["a","b","c","d","e","f","g","h"]

Per trovare le occorrenze di qualsiasi elemento, ad esempio b arr['b']verrà visualizzato2


Per favore, non pubblicare solo il codice come risposta, ma includi anche una spiegazione di cosa fa il tuo codice e come risolve il problema. Le risposte con una spiegazione sono generalmente di qualità superiore e hanno maggiori probabilità di attirare voti positivi.
Mark Rotteveel

0

Utilizzo:

wrap.common.getUniqueDataCount(, columnName);

CODICE:

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

Frammento

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


-1

È semplice in JavaScript utilizzando il metodo di riduzione dell'array:

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 }

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.