Cách đếm giá trị trùng lặp trong một mảng trong javascript


100

Hiện tại, tôi nhận được một mảng như thế:

var uniqueCount = Array();

Sau một vài bước, mảng của tôi trông như thế này:

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

Làm cách nào để đếm được có bao nhiêu a, b, c trong mảng? Tôi muốn có kết quả như sau:

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

Vân vân.



@Nirk Tôi đoán rằng music_coder có nghĩa là một bản đồ như trong {}, không phải của lập trình chức năng map.
Matt Ball

Câu trả lời:


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

Bạn cũng có thể sử dụng các hàm bậc cao hơn để thực hiện thao tác. Xem câu trả lời này


1
câu lệnh if bổ sung sau vòng lặp là không cần thiết ... chỉ cần sử dụng for (var i = 0; i <= array_elements.length; i++) {hoặc <=thay vì <.
EmmaGamma

Xin chào @Vinay, có thể bạn có thể giúp tôi ở đây? stackoverflow.com/questions/57819850/…
SMPLYJR

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

9
Đây chắc chắn là câu trả lời đơn giản nhất
Josh Beam

3
(counts [x] || 0) +1 cách tính như thế nào đây?
jsduniya

5
@SidBhalke: Biểu thức counts[x] || 0trả về giá trị counts[x]nếu nó được đặt, nếu không 0. Sau đó, chỉ cần thêm một và đặt nó một lần nữa trong đối tượng và số lượng được thực hiện.
Constantinius

1
@SheetJS nếu bạn đang thắc mắc tại sao lại phản đối - đó là tôi; Tôi đang duyệt trên thiết bị di động và đã nhấp vào nút mà thực sự nhận thấy. Khi tôi phát hiện ra thì đã quá muộn để hoàn nguyên. Xin lỗi vì điều đó, câu trả lời là thực sự tốt. Nếu bạn muốn chỉnh sửa nó, tôi rất vui được đảo ngược.
Todor Minakov

4
Cũng với reduce:var counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
Alberto89,

70

Một cái gì đó như thế này:

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

Sử dụng vòng lặp for đơn giản thay vì forEach nếu bạn không muốn điều này bị hỏng trong các trình duyệt cũ hơn.


4
@web_dev anh ấy tạo một đối tượng mảng kết hợp được gọi là count sẽ có một cặp giá trị khóa cho mỗi phần tử duy nhất trong mảng, trong đó khóa là giá trị phần tử duy nhất và giá trị là số đếm. Anh ta lặp qua mảng và đối với mỗi giá trị hoặc tăng giá trị hoặc tạo cặp giá trị khóa (giá trị của khóa không tồn tại được đánh giá là không xác định, vì vậy toán tử || hoặc lấy số 0 thay thế và thêm số 1)
robisrob

@neelmeg lẽ viết tất cả các thông số cho "foreach" giúp tốt hơn để hiểu ( "i" là mỗi giá trị mảng và KHÔNG nó index):uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
Pedro Ferreira

Cách tốt để đi thêm một bước và sắp xếp theo tổng số sẽ là gì?
run

37

Tôi tình cờ gặp câu hỏi (rất cũ) này. Điều thú vị là giải pháp rõ ràng và thanh lịch nhất (imho) bị thiếu: Array.prototype.reduce (...) . Tất cả các trình duyệt chính đều hỗ trợ tính năng này kể từ khoảng năm 2011 (IE) hoặc thậm chí trước đó (tất cả các trình duyệt khác):

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

Một dòng dựa trên hàm giảm mảng

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


Tôi vừa nhận ra rằng @ isnot2bad ( stackoverflow.com/a/32886673/621058 ) gần giống với của tôi. Tôi chỉ xảy ra để sử dụng chức năng mũi tên chất béo và hằng
dinigo

8

Đơn giản là tốt hơn, một biến, một hàm :)

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

6

Tôi nghĩ đây là cách đơn giản nhất để đếm số lần xuất hiện có cùng giá trị trong mảng.

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

Có vẻ như không ai phản hồi đang sử dụng Map()cài sẵn cho việc này, điều này có xu hướng là mục tiêu của tôi kết hợp với 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, bạn sẽ phải polyfillMap() nếu muốn sử dụng nó trong các trình duyệt cũ hơn.


Bạn có thể giải thích một chút chuyên sâu về cách thức hoạt động của nó không? (đặc biệt là bộ / nhận được một phần). Tôi đã cố gắng phá vỡ bộ giảm thiểu thành một hàm nhưng tôi có "get" không phải là một hàm trong phản hồi.
Antoine Nedelec

Ok getvà các setchức năng đến từ Mapđối tượng. Nhưng bộ tích lũy ban đầu không phải là một đối tượng Bản đồ, vậy tại sao phiên bản thu gọn của bộ giảm tốc lại lấy một cái?
Antoine Nedelec

@AntoineNedelec Giá trị ban đầu một Mapđối tượng mới ; xem đối số thứ hai của giảm. Map.prototype.settrả về đối tượng bản đồ và Map.prototype.gettrả về undefinedhoặc giá trị của bất kỳ khóa nào được cung cấp cho nó. Điều này cho phép chúng tôi nhận được số lượng hiện tại của mỗi chữ cái (hoặc 0nếu không được xác định), sau đó tăng số đó lên một, sau đó đặt số lượng của chữ cái đó thành số mới, trả về bản đồ và trở thành giá trị tích lũy mới.
aendrew

4

Bạn có thể có một đối tượng chứa số lượng. Xem qua danh sách và tăng số lượng cho từng phần tử:

var counts = {};

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

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

tại sao bạn đặt điều kiện này counts[element] || 0?
AskMen

Lần đầu tiên truy cập counts[element]trả về undefinedvì thuộc tính chưa có giá trị. Nếu sau đó bạn cố gắng thêm undefined + 1, bạn sẽ kết thúc với NaN . Các (count[element] || 0)sẽ thay thế undefinedvới 0nên thêm 1sản xuất 1thay vì NaN. ECMAScript 2020 thêm toán tử kết hợp nullish ??thực hiện một điều tương tự nhưng rõ ràng hơn một chút rằng nó đang sử dụng giá trị thứ hai khi giá trị đầu tiên là undefined(hoặc null). Phiên bản đó sẽ là (counts[element] ?? 0) + 1.
nkron

4

Bạn có thể giải quyết nó mà không cần sử dụng bất kỳ vòng lặp for / while ou forEach nào.

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

Hy vọng nó sẽ giúp bạn!


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

Bạn có thể làm điều gì đó như vậy:

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

bây giờ bạn có một bản đồ với tất cả các ký tự


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

Cảm ơn bạn đã cập nhật nó, rất nhiều hữu ích cho những người bắt đầu.
Joe thường lệ vào

1

Các bản sao trong một mảng chứa các bảng chữ cái:

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

Các bản sao trong một mảng chứa các số:

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

câu trả lời sheet.js đơn giản hóa

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


0

Tổng hợp các câu trả lời hay:

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

Hy vọng nó hữu ích.


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

}   

}


Bạn có thể thêm một số bối cảnh xung quanh điều này?
Neo

0

Bằng cách sử dụng array.map, chúng ta có thể giảm vòng lặp, hãy xem điều này trên 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;
}

Để kiểm tra:

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

Ví dụ demo.js, tạo một tệp và chạy nó trong bảng điều khiển với nút demo.jsvà bạn sẽ nhận được sự xuất hiện của các phần tử ở dạng ma trận.

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

Bạn sẽ nhận được kết quả trong bảng điều khiển như sau:

[ 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

Cách nhanh nhất:

Độ phức tạp tính toán là 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']);

Mã ngắn nhất:

Sử dụng 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

Khai báo một đối tượng arrđể giữ tập hợp duy nhất làm khóa. Dân cưarr bằng cách lặp qua mảng một lần sử dụng bản đồ. Nếu khóa chưa được tìm thấy trước đó thì hãy thêm khóa và gán giá trị bằng không. Trên mỗi lần lặp, giá trị của khóa sẽ tăng lên.

Đã cho testArray:

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

giải pháp:

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

JSON.stringify(arr) sẽ xuất ra

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

Object.keys(arr) sẽ trở lại ["a","b","c","d","e","f","g","h"]

Để tìm sự xuất hiện của bất kỳ mục nào, ví dụ b arr['b']sẽ xuất2


Vui lòng không chỉ đăng mã dưới dạng câu trả lời, mà hãy bao gồm giải thích mã của bạn có chức năng gì và cách nó giải quyết vấn đề. Các câu trả lời kèm theo lời giải thích thường có chất lượng cao hơn và có nhiều khả năng thu hút sự ủng hộ hơn.
Mark Rotteveel

0

Nó đơn giản trong javascript bằng cách sử dụng phương thức giảm mảng:

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 }


0

Sử dụng:

wrap.common.getUniqueDataCount(, columnName);

MÃ:

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

Đoạn trích

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.