Jak policzyć zduplikowaną wartość w tablicy w javascript

100

Obecnie mam taką tablicę:

var uniqueCount = Array();

Po kilku krokach moja tablica wygląda tak:

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

Jak mogę policzyć, ile a, b, c znajduje się w tablicy? Chcę uzyskać taki wynik:

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

itp.

detno29
źródło
1
możliwy duplikat stackoverflow.com/questions/12749200/ ...
Vinay Pratap Singh
@Nirk Zakładam, że musical_coder oznaczał mapę, a {}nie programowanie funkcjonalne map.
Matt Ball

Odpowiedzi:

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

Do wykonania tej operacji można również użyć funkcji wyższego rzędu. Zobacz tę odpowiedź

Vinay Pratap Singh
źródło
1
dodatkowa instrukcja if po pętli jest niepotrzebna ... po prostu użyj for (var i = 0; i <= array_elements.length; i++) {lub <=zamiast <.
EmmaGamma,
Cześć @Vinay, może mógłbyś mi tutaj pomóc? stackoverflow.com/questions/57819850/…
SMPLYJR
322
var counts = {};
your_array.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
SheetJS
źródło
9
To zdecydowanie najprostsza odpowiedź
Josh Beam
3
(liczy [x] || 0) +1 jak to daje licznik?
jsduniya
6
@SidBhalke: Wyrażenie counts[x] || 0zwraca wartość, counts[x]jeśli jest ustawione, w przeciwnym razie 0. Następnie po prostu dodaj jeden i ustaw go ponownie w obiekcie, a liczenie jest zakończone.
Constantinius,
1
@SheetJS, jeśli zastanawiasz się, dlaczego głos przeciw - to byłem ja; Przeglądałem na telefonie komórkowym i kliknąłem przycisk, nie zauważając. Kiedy się dowiedziałem, było za późno na powrót. Przepraszam za to, odpowiedź jest naprawdę dobra. Jeśli chcesz go edytować, z przyjemnością cofnę.
Todor Minakov
4
Również z reduce:var counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
Alberto89
70

Coś takiego:

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

Użyj prostej pętli for zamiast forEach, jeśli nie chcesz, aby to się zepsuło w starszych przeglądarkach.

loxxy
źródło
4
@web_dev tworzy asocjacyjny obiekt tablicy o nazwie count, który będzie miał parę klucz-wartość dla każdego unikalnego elementu w tablicy, gdzie klucz jest unikalną wartością elementu, a wartością jest liczba. Iteruje po tablicy i dla każdej wartości albo zwiększa wartość, albo tworzy parę klucz-wartość (wartość nieistniejącego klucza przyjmuje wartość undefined, więc operator || lub przyjmuje zero zamiast tego i dodaje 1)
robisrob
@neelmeg Być może zapisanie wszystkich parametrów dla „forEach” pomoże lepiej zrozumieć („i” to każda wartość tablicy, a NIE jest to índex):uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
Pedro Ferreira
jaki byłby dobry sposób na wykonanie dodatkowego kroku i posortowanie według liczby całkowitej?
drżenie
38

Natknąłem się na to (bardzo stare) pytanie. Co ciekawe, brakuje najbardziej oczywistego i eleganckiego rozwiązania (imho): Array.prototype.reduce (...) . Wszystkie główne przeglądarki obsługują tę funkcję od około 2011 roku (IE) lub nawet wcześniej (wszystkie inne):

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
źródło
10

Pojedyncza linia oparta na funkcji redukcji tablicy

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
źródło
Właśnie zdałem sobie sprawę, że @ isnot2bad ( stackoverflow.com/a/32886673/621058 ) jest prawie takie samo jak moje. Po prostu używam funkcji grubych strzałek i stałych
dinigo
8

Proste jest lepsze, jedna zmienna, jedna funkcja :)

const counts = arr.reduce((acc, value) => ({
   ...acc,
   [value]: (acc[value] || 0) + 1
}), {});
Shannon Hochkins
źródło
6

Myślę, że to najprostszy sposób zliczania wystąpień o tej samej wartości w tablicy.

var a = [true, false, false, false];
a.filter(function(value){
    return value === false;
}).length                                      
Dmytro Kozlovskyi
źródło
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
źródło
5

Wygląda na to, że nikt nie odpowiadający nie używa do tego Map()wbudowanego, co zwykle jest moim celem w połączeniu z 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);

Uwaga,Map() jeśli chcesz używać go w starszych przeglądarkach , musisz go wypełnić .

aendrew
źródło
Czy mógłbyś wyjaśnić trochę szczegółowo, jak to działa? (szczególnie część set / get). Próbowałem przełamać reduktor na funkcję, ale mam „get” nie jest funkcją w odpowiedzi.
Antoine Nedelec
Ok, geta setfunkcje pochodzą z Mapobiektu. Ale początkowy akumulator nie jest obiektem Map, więc dlaczego zredukowana wersja reduktora go zajmuje?
Antoine Nedelec
@AntoineNedelec Wartość początkowa to nowy Mapobiekt; patrz drugi argument redukcji. Map.prototype.setzwraca obiekt mapy i Map.prototype.getzwraca undefinedlub wartość dowolnego dostarczonego klucza. To pozwala nam uzyskać bieżącą liczbę każdej litery (lub 0jeśli jest niezdefiniowana), następnie zwiększyć ją o jeden, a następnie ustawić liczbę tej litery na nową liczbę, która zwraca mapę i staje się nową wartością akumulatora.
aendrew
4

Możesz mieć obiekt zawierający liczby. Przejdź przez listę i zwiększ liczbę dla każdego elementu:

var counts = {};

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

for (var element in counts) {
  console.log(element + ' = ' + counts[element]);
} 
nkron
źródło
dlaczego ustawiłeś ten warunek counts[element] || 0?
AskMen
Pierwsze uzyskanie dostępu counts[element]zwraca, undefinedponieważ właściwość nie ma jeszcze wartości. Jeśli następnie spróbujesz dodać undefined + 1, skończysz z NaN . (count[element] || 0)Zastąpi undefinedsię 0więc dodanie 1produkuje 1zamiast NaN. ECMAScript 2020 dodaje zerowy operator koalescencyjny, ??który robi podobną rzecz, ale jest nieco bardziej wyraźny, że używa drugiej wartości, gdy pierwsza to undefined(lub null). Taka byłaby wersja (counts[element] ?? 0) + 1.
nkron
4

Możesz go rozwiązać bez używania pętli for / while lub forEach.

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

Mam nadzieję, że ci to pomoże!

Pablo Souza
źródło
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
źródło
3

Możesz zrobić coś takiego:

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

teraz masz mapę z liczbą wszystkich znaków

Rami
źródło
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
źródło
Dzięki za aktualizację, dużo bardziej pomocne dla początkujących.
Zwykły Joe
1

Duplikaty w tablicy zawierającej alfabety:

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

Duplikaty w tablicy zawierającej liczby:

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
źródło
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);
user6160741
źródło
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
źródło
1

Uproszczony answare Sheet.js.

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

ßãlãjî
źródło
1

Jest to proste w javascript przy użyciu metody redukcji tablicy:

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
źródło
0

Połączenie dobrych odpowiedzi:

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

Mam nadzieję, że to pomocne.

Xiaodan Mao
źródło
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
źródło
Czy możesz dodać kontekst do tego?
Mister Positive
0

Używając array.map możemy zredukować pętlę, zobacz to na 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;
}

Testować:

var test = new Check(1,2,1,4,1);
console.log(test);
Ali Adravi
źródło
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
źródło
0

Stwórz np. Plik demo.jsi uruchom go w konsoli z węzłem demo.jsa otrzymasz wystąpienie elementów w postaci macierzy.

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

Otrzymasz wynik w konsoli jak poniżej:

[ 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
źródło
0

Najszybszy sposób:

Złożoność obliczeniowa to 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']);

Najkrótszy kod:

Użyj 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
źródło
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;
}
łapki
źródło
0

Zadeklaruj obiekt arrdo przechowywania unikalnego zestawu jako kluczy. Zaludniaćarr , przechodząc w pętli przez tablicę, używając map. Jeśli klucz nie został wcześniej znaleziony, dodaj klucz i przypisz mu wartość zero. Przy każdej iteracji zwiększ wartość klucza.

Podany test Tablica:

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

rozwiązanie:

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

JSON.stringify(arr) wyjdzie

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

Object.keys(arr) wróci ["a","b","c","d","e","f","g","h"]

Aby znaleźć wystąpienia dowolnego elementu, na przykład arr['b']wyświetli się b2

jidexl21
źródło
Nie wysyłaj tylko kodu jako odpowiedzi, ale dołącz też wyjaśnienie, co robi Twój kod i jak rozwiązuje problem. Odpowiedzi z wyjaśnieniem są na ogół wyższej jakości i częściej przyciągają głosy za.
Mark Rotteveel
0

Stosowanie:

wrap.common.getUniqueDataCount(, columnName);

KOD:

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

Skrawek

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
źródło