วิธีนับค่าที่ซ้ำกันในอาร์เรย์ในจาวาสคริปต์


100

ตอนนี้ฉันมีอาร์เรย์แบบนั้น:

var uniqueCount = Array();

หลังจากไม่กี่ขั้นตอนอาร์เรย์ของฉันจะมีลักษณะดังนี้:

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

ฉันจะนับจำนวน a, b, c ในอาร์เรย์ได้อย่างไร ฉันต้องการได้ผลลัพธ์ดังนี้:

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

เป็นต้น


1
เป็นไปได้ที่จะซ้ำกันของstackoverflow.com/questions/12749200/…
Vinay Pratap Singh

@Nirk ฉันเข้าใจ musical_coder นั่นหมายความว่าแผนที่ในขณะที่การเขียนโปรแกรมไม่ทำงานของ{} map
Matt Ball

คำตอบ:


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

สาธิตซอ

คุณสามารถใช้ฟังก์ชันลำดับที่สูงกว่าเพื่อดำเนินการได้เช่นกัน ดูคำตอบนี้


1
คำสั่ง if พิเศษหลังลูปนั้นไม่จำเป็น ... เพียงแค่ใช้for (var i = 0; i <= array_elements.length; i++) {หรือ<=แทนที่จะ<ใช้
EmmaGamma

สวัสดี @ Vinay คุณช่วยฉันได้ไหม stackoverflow.com/questions/57819850/…
SMPLYJR

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

9
นี่เป็นคำตอบที่ง่ายที่สุดอย่างแน่นอน
Josh Beam

3
(counts [x] || 0) +1 นี่คือการนับอย่างไร?
jsduniya

6
@SidBhalke: การแสดงออกcounts[x] || 0ผลตอบแทนที่คุ้มค่าของการหากมีการตั้งมิฉะนั้นcounts[x] 0จากนั้นเพิ่มหนึ่งและตั้งค่าอีกครั้งในวัตถุและการนับเสร็จสิ้น
Constantinius

1
@SheetJS ถ้าคุณสงสัยว่าทำไมโหวตลง - มันคือฉัน; ฉันกำลังท่องเว็บบนมือถือและได้คลิกปุ่มโดยไม่สังเกตเห็นจริงๆ เมื่อฉันพบว่ามันสายเกินไปที่จะเปลี่ยนกลับ ขออภัยสำหรับคำตอบที่ดีจริงๆ หากคุณต้องการแก้ไขฉันยินดีที่จะย้อนกลับ
Todor Minakov

4
นอกจากนี้กับreduce:var counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
Alberto89

70

สิ่งนี้:

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

ใช้ simple for loop แทน forEach หากคุณไม่ต้องการให้เบราว์เซอร์รุ่นเก่าพัง


4
@web_dev เขาสร้างวัตถุอาร์เรย์เชื่อมโยงที่เรียกว่า count ซึ่งจะมีคู่ค่าคีย์สำหรับแต่ละองค์ประกอบที่ไม่ซ้ำกันในอาร์เรย์โดยที่คีย์คือค่าองค์ประกอบที่ไม่ซ้ำกันและค่าคือจำนวนนับ เขาวนซ้ำบนอาร์เรย์และสำหรับแต่ละค่าจะเพิ่มค่าหรือสร้างคู่ค่าคีย์ (ค่าของคีย์ที่ไม่มีอยู่จริงจะประเมินเป็นไม่ได้กำหนดดังนั้น || หรือตัวดำเนินการจึงนำศูนย์แทนและเพิ่ม 1)
robisrob

@neelmeg บางทีการเขียนพารามิเตอร์ทั้งหมดสำหรับ "forEach" จะช่วยให้เข้าใจได้ดีขึ้น ("i" คือค่าอาร์เรย์แต่ละค่าไม่ใช่índex):uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
Pedro Ferreira

วิธีใดเป็นวิธีที่ดีในการก้าวไปอีกขั้นและจัดเรียงตามจำนวนรวม
อาการสั่น

38

ฉันเจอคำถามนี้ (เก่ามาก) ที่น่าสนใจการแก้ปัญหาที่ชัดเจนที่สุดและสง่างาม imho () หายไป: Array.prototype.reduce ( ... ) เบราว์เซอร์หลักทั้งหมดรองรับคุณสมบัตินี้ตั้งแต่ประมาณปี 2011 (IE) หรือก่อนหน้า (อื่น ๆ ทั้งหมด):

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

บรรทัดเดียวขึ้นอยู่กับฟังก์ชันลดอาร์เรย์

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


ฉันเพิ่งรู้ว่า @ isnot2bad ( stackoverflow.com/a/32886673/621058 ) เกือบจะเหมือนกับของฉัน ฉันเพิ่งใช้ฟังก์ชัน fat arrow และค่าคงที่
dinigo

8

ง่ายดีกว่าตัวแปรเดียวฟังก์ชั่นเดียว :)

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

6

ฉันคิดว่านี่เป็นวิธีที่ง่ายที่สุดในการนับเหตุการณ์ที่มีค่าเดียวกันในอาร์เรย์

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

ดูเหมือนจะไม่มีใครตอบสนองโดยใช้Map()บิวท์อินสำหรับสิ่งนี้ซึ่งมีแนวโน้มที่จะไปรวมกับ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 คุณจะต้องทำpolyfillMap()หากต้องการใช้ในเบราว์เซอร์รุ่นเก่า


คุณช่วยอธิบายเชิงลึกเล็กน้อยว่ามันทำงานอย่างไร (โดยเฉพาะชุด / รับส่วน) ฉันพยายามแบ่งตัวลดออกเป็นฟังก์ชัน แต่ฉันมี "get" ไม่ใช่ฟังก์ชันในการตอบสนอง
Antoine Nedelec

ตกลงgetและsetฟังก์ชั่นมาจากMapวัตถุ แต่ตัวสะสมเริ่มต้นไม่ใช่วัตถุแผนที่ดังนั้นเหตุใดตัวลดรุ่นที่ลดลงจึงใช้ตัวลดขนาดเดียว?
Antoine Nedelec

@AntoineNedelec ค่าเริ่มต้นคือMapวัตถุใหม่ ดูอาร์กิวเมนต์ที่สองของการลด Map.prototype.setส่งคืนอ็อบเจ็กต์แผนที่และMap.prototype.getส่งคืนundefinedหรือค่าของคีย์ใด ๆ ที่ให้มา สิ่งนี้ช่วยให้เราได้จำนวนปัจจุบันของแต่ละตัวอักษร (หรือ0ถ้าไม่ได้กำหนด) จากนั้นเพิ่มทีละตัวจากนั้นตั้งค่าการนับของตัวอักษรนั้นเป็นจำนวนใหม่ซึ่งจะส่งคืนแผนที่และกลายเป็นค่าตัวสะสมใหม่
aendrew

4

คุณสามารถมีวัตถุที่มีจำนวนนับ เดินผ่านรายการและเพิ่มจำนวนสำหรับแต่ละองค์ประกอบ:

var counts = {};

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

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

คุณไม่ตั้งเงื่อนไขนี้ทำไม counts[element] || 0?
AskMen

ครั้งแรกที่เข้าถึงcounts[element]ผลตอบแทนundefinedเนื่องจากคุณสมบัติยังไม่มีค่า จากนั้นถ้าคุณพยายามที่จะเพิ่มundefined + 1คุณจะจบลงด้วยน่าน (count[element] || 0)จะแทนที่undefinedด้วย0เพื่อเพิ่ม1ผลิตแทน1 NaNECMAScript 2020 เพิ่มตัวดำเนินการการรวมตัวกันเป็นโมฆะ??ซึ่งทำสิ่งที่คล้ายกัน แต่ค่อนข้างชัดเจนว่ากำลังใช้ค่าที่สองเมื่อค่าแรกเป็นundefined(หรือnull) (counts[element] ?? 0) + 1รุ่นที่จะเป็น
nkron

4

คุณสามารถแก้ปัญหาได้โดยไม่ต้องใช้ for / while ลูปสำหรับแต่ละคน

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

หวังว่ามันจะช่วยคุณได้!



3

คุณสามารถทำสิ่งนั้นได้:

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

ตอนนี้คุณมีแผนที่พร้อมจำนวนอักขระทั้งหมด


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

ขอบคุณสำหรับการอัปเดตซึ่งมีประโยชน์มากขึ้นสำหรับผู้เริ่มต้น
ปกติ Joe

1

รายการที่ซ้ำกันในอาร์เรย์ที่มีตัวอักษร:

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

รายการที่ซ้ำกันในอาร์เรย์ที่มีตัวเลข:

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

เป็นเรื่องง่ายในจาวาสคริปต์โดยใช้วิธีลดอาร์เรย์:

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

คำตอบที่ดีรวมกัน:

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

หวังว่าจะเป็นประโยชน์


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

}   

}


คุณสามารถเพิ่มบริบทเกี่ยวกับเรื่องนี้ได้ไหม
Mister Positive

0

ด้วยการใช้ array.map เราสามารถลดลูปได้ดูสิ่งนี้ใน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;
}

ทดสอบ:

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

สร้างไฟล์ตัวอย่างdemo.jsและเรียกใช้ในคอนโซลที่มีโหนดdemo.jsและคุณจะได้รับการเกิดขึ้นขององค์ประกอบในรูปแบบของเมทริกซ์

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

คุณจะได้รับผลลัพธ์ในคอนโซลดังต่อไปนี้:

[ 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

วิธีที่เร็วที่สุด:

ความซับซ้อนของการคำนวณคือ 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']);

รหัสที่สั้นที่สุด:

ใช้ 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

ประกาศวัตถุarrเพื่อยึดชุดเฉพาะเป็นกุญแจ เติมข้อมูลarrโดยการวนลูปผ่านอาร์เรย์หนึ่งครั้งโดยใช้แผนที่ หากไม่พบคีย์ก่อนหน้านี้ให้เพิ่มคีย์และกำหนดค่าเป็นศูนย์ ในการทำซ้ำแต่ละครั้งจะเพิ่มค่าของคีย์

ให้ testArray:

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

วิธีการแก้:

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

JSON.stringify(arr) จะส่งออก

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

Object.keys(arr) จะกลับมา ["a","b","c","d","e","f","g","h"]

เพื่อค้นหาการเกิดขึ้นของรายการใด ๆ เช่น b arr['b']จะแสดงผล2


โปรดอย่าโพสต์โค้ดเพื่อเป็นคำตอบเท่านั้น แต่ต้องใส่คำอธิบายด้วยว่าโค้ดของคุณใช้ทำอะไรและแก้ปัญหาได้อย่างไร คำตอบพร้อมคำอธิบายมักจะมีคุณภาพสูงกว่าและมีแนวโน้มที่จะดึงดูดการโหวตได้มากกว่า
Mark Rotteveel

0

การใช้งาน:

wrap.common.getUniqueDataCount(, columnName);

รหัส:

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

ตัวอย่างข้อมูล

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.