ฉันมีอาเรย์:
[1, 2, 3, 5, 2, 8, 9, 2]
ฉันต้องการที่จะรู้ว่ามีกี่2s ในอาร์เรย์
เป็นวิธีที่ดีที่สุดในการทำใน JavaScript โดยไม่วนกับforวนคืออะไร
ฉันมีอาเรย์:
[1, 2, 3, 5, 2, 8, 9, 2]
ฉันต้องการที่จะรู้ว่ามีกี่2s ในอาร์เรย์
เป็นวิธีที่ดีที่สุดในการทำใน JavaScript โดยไม่วนกับforวนคืออะไร
คำตอบ:
ง่ายมาก:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);และรายละเอียดการปฏิบัติสามารถโต้เถียงได้
[ คำตอบนี้เก่าไปหน่อย: อ่านการแก้ไข ]
ทักทายเพื่อนของคุณ: mapและfilterและreduceและforEachและeveryอื่น ๆ
(ในบางครั้งฉันเขียนแบบ for-loops ใน javascript เท่านั้นเนื่องจากการกำหนดขอบเขตบล็อกหายไปดังนั้นคุณต้องใช้ฟังก์ชั่นเป็นเนื้อหาของลูปถ้าคุณต้องการจับหรือโคลนดัชนีการวนซ้ำหรือค่าของคุณ โดยทั่วไปจะมีประสิทธิภาพมากกว่า แต่บางครั้งคุณจำเป็นต้องปิดตัวลง)
วิธีที่อ่านง่ายที่สุด:
[....].filter(x => x==2).length
(เราน่าจะเขียน.filter(function(x){return x==2}).lengthแทน)
ต่อไปนี้เป็นพื้นที่ที่มีประสิทธิภาพมากขึ้น (O (1) มากกว่า O (N)) แต่ฉันไม่แน่ใจว่าคุณจะได้รับผลประโยชน์ / การลงโทษเท่าใดในแง่ของเวลา (ไม่มากกว่าปัจจัยคงที่ตั้งแต่คุณเยี่ยมชม แต่ละองค์ประกอบตรงหนึ่งครั้ง):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(หากคุณต้องการเพิ่มประสิทธิภาพโค้ดเฉพาะชิ้นนี้ a สำหรับลูปอาจเร็วกว่าในเบราว์เซอร์บางตัว ... คุณสามารถทดสอบสิ่งต่าง ๆ บน jsperf.com)
จากนั้นคุณสามารถสง่างามและเปลี่ยนเป็นฟังก์ชั่นต้นแบบ:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
แบบนี้:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
นอกจากนี้คุณยังสามารถใช้เทคนิค for-loop แบบเก่า (ดูคำตอบอื่น ๆ ) ในคำจำกัดความด้านบน (อีกครั้งซึ่งน่าจะเร็วกว่ามาก)
2017 แก้ไข :
อ๊ะคำตอบนี้ได้รับความนิยมมากกว่าคำตอบที่ถูกต้อง ที่จริงแล้วเพียงใช้คำตอบที่ยอมรับได้ ในขณะที่คำตอบนี้อาจจะน่ารัก, js คอมไพเลอร์อาจไม่ (หรือไม่สามารถเนื่องจากสเป็ค) เพิ่มประสิทธิภาพกรณีดังกล่าว ดังนั้นคุณควรเขียนง่าย ๆ สำหรับลูป:
Object.defineProperties(Array.prototype, {
count: {
value: function(query) {
/*
Counts number of occurrences of query in array, an integer >= 0
Uses the javascript == notion of equality.
*/
var count = 0;
for(let i=0; i<this.length; i++)
if (this[i]==query)
count++;
return count;
}
}
});
คุณสามารถกำหนดเวอร์ชัน.countStrictEq(...)ที่ใช้===แนวคิดเรื่องความเท่าเทียมกัน แนวคิดเรื่องความเท่าเทียมอาจมีความสำคัญต่อสิ่งที่คุณทำ! (ตัวอย่างเช่น[1,10,3,'10'].count(10)==2เนื่องจากตัวเลขเช่น '4' == 4 ใน javascript ... ดังนั้นจึงเรียกมัน.countEqหรือ.countNonstrictเน้นว่าจะใช้==โอเปอเรเตอร์)
ลองพิจารณาใช้โครงสร้างข้อมูลหลายเซ็ตของคุณเอง (เช่น python ' collections.Counter') เพื่อหลีกเลี่ยงการนับในตอนแรก
class Multiset extends Map {
constructor(...args) {
super(...args);
}
add(elem) {
if (!this.has(elem))
this.set(elem, 1);
else
this.set(elem, this.get(elem)+1);
}
remove(elem) {
var count = this.has(elem) ? this.get(elem) : 0;
if (count>1) {
this.set(elem, count-1);
} else if (count==1) {
this.delete(elem);
} else if (count==0)
throw `tried to remove element ${elem} of type ${typeof elem} from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)`;
// alternatively do nothing {}
}
}
การสาธิต:
> counts = new Multiset([['a',1],['b',3]])
Map(2) {"a" => 1, "b" => 3}
> counts.add('c')
> counts
Map(3) {"a" => 1, "b" => 3, "c" => 1}
> counts.remove('a')
> counts
Map(2) {"b" => 3, "c" => 1}
> counts.remove('a')
Uncaught tried to remove element a of type string from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)
sidenote: แม้ว่าถ้าคุณยังต้องการวิธีการทำงานเขียนโปรแกรม (หรือใบปลิวหนึ่งซับโดยไม่ต้องเอาชนะ Array.prototype) [...].filter(x => x==2).lengthคุณสามารถเขียนมันมากขึ้นในปัจจุบันเป็นกะทัดรัด หากคุณใส่ใจกับประสิทธิภาพโปรดทราบว่าแม้ว่านี่จะเป็น asymptotically ประสิทธิภาพเดียวกันกับเวลา for-loop (O (N)) ก็อาจต้องใช้หน่วยความจำเสริม O (N) (แทน O (1) หน่วยความจำ) เพราะมันจะเกือบ แน่นอนสร้างอาร์เรย์กลางแล้วนับองค์ประกอบของอาร์เรย์กลางนั้น
array.reduce(function(total,x){return x==value? : total+1 : total}, 0)
[...].reduce(function(total,x){return x==2 ? total+1 : total}, 0)
const count = (list) => list.filter((x) => x == 2).lengthการแก้ปัญหา: จากนั้นใช้มันโดยการโทรหาcount(list)list คืออาร์เรย์ของตัวเลข คุณสามารถทำได้const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthเพื่อนับอินสแตนซ์ของ crazyValue ในอาร์เรย์ของวัตถุ หมายเหตุมันเป็นการจับคู่แบบตรงทั้งหมดสำหรับคุณสมบัติ
อัพเดต ES6 เป็น JS:
โปรดทราบว่าคุณควรใช้สามเท่ากับเสมอ===เพื่อรับการเปรียบเทียบที่ถูกต้อง:
// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]
// Functional filter with an Arrow function
array.filter(x => x === 2).length // -> 3
ฟังก์ชันลูกศรเป็นเอกฉันท์ต่อไปนี้(ฟังก์ชันแลมบ์ดา) ใน JS:
(x) => {
const k = 2
return k * x
}
อาจลดความซับซ้อนของรูปแบบย่อนี้สำหรับอินพุตเดี่ยว:
x => 2 * x
ที่returnบอกเป็นนัย ๆ
2017: หากมีใครยังคงสนใจในคำถามโซลูชันของฉันมีดังต่อไปนี้:
const arrayToCount = [1, 2, 3, 5, 2, 8, 9, 2];
const result = arrayToCount.filter(i => i === 2).length;
console.log('number of the found elements: ' + result);
หากคุณใช้ lodash หรือขีดเส้นใต้เมธอด_.countByจะจัดเตรียมออบเจ็กต์ของผลรวมรวมที่คีย์โดยแต่ละค่าในอาร์เรย์ คุณสามารถเปลี่ยนสิ่งนี้ให้เป็นหนึ่งซับได้ถ้าคุณเพียงต้องการนับหนึ่งค่า:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
นอกจากนี้ยังทำงานได้ดีในอาร์เรย์ของตัวเลข ซับในสำหรับตัวอย่างของคุณคือ:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
วิธีที่แปลกประหลาดที่สุดที่ฉันสามารถทำได้คือ:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
ที่ไหน:
ข้อเสนอแนะของฉันใช้เวลาสักครู่หรือเพื่อลูป ;-)
ไม่ได้ใช้ห่วงมักจะหมายถึงการมอบกระบวนการมากกว่าที่จะใช้วิธีการบางอย่างที่ไม่ใช้ห่วง
นี่เป็นวิธีที่ผู้ให้รหัสที่เกลียดชังของเราสามารถตอบสนองความเกลียดชังของเขาได้ในราคา:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
นอกจากนี้คุณยังสามารถเรียก indexOf ซ้ำ ๆ ได้หากมีวิธีการแบบอาร์เรย์และย้ายตัวชี้การค้นหาในแต่ละครั้ง
สิ่งนี้ไม่ได้สร้างอาร์เรย์ใหม่และการวนซ้ำนั้นเร็วกว่า forEach หรือตัวกรอง
มันอาจสร้างความแตกต่างได้หากคุณมีสมาชิกนับล้านคนที่จะดู
function countItems(arr, what){
var count= 0, i;
while((i= arr.indexOf(what, i))!= -1){
++count;
++i;
}
return count
}
countItems(a,2)
/* returned value: (Number)
3
*/
String(a).match(/2/g).length + 1- แต่ระวังนี้หรือการใช้งานของคุณจะไม่เล่นดีกับตัวเลขสองหลัก
โซลูชันที่โพสต์ส่วนใหญ่ที่ใช้ฟังก์ชันอาร์เรย์เช่นตัวกรองไม่สมบูรณ์เนื่องจากไม่ได้กำหนดค่าพารามิเตอร์
ต่อไปนี้เป็นวิธีการแก้ปัญหาที่องค์ประกอบที่จะนับสามารถตั้งค่าในเวลาทำงาน
function elementsCount(elementToFind, total, number){
return total += number==elementToFind;
}
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(elementsCount.bind(this, elementToFind), 0);
ข้อดีของวิธีนี้คือสามารถเปลี่ยนฟังก์ชั่นให้นับตัวอย่างได้อย่างง่ายดายเช่นจำนวนองค์ประกอบที่มากกว่า X
คุณอาจประกาศลดฟังก์ชั่นแบบอินไลน์
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(function (elementToFind, total, number){
return total += number==elementToFind;
}.bind(this, elementToFind), 0);
var elementToFind=2; ... function (elementToFind, total, number){ return total += number==elementToFind; }.bind(this, elementToFind) ...ยากต่อการอ่านและไม่ได้เปรียบ... (acc, x) => acc += number == 2...อะไรเลย ผมชอบการใช้งานของ+=แทนacc + (number == 2)ว่า รู้สึกเหมือนแฮ็กไวยากรณ์ที่ไม่รับประกันว่า
จริง ๆ แล้วทำไมคุณต้องการmapหรือfilterเพื่อสิ่งนี้
reduceเป็น "เกิด" สำหรับการทำงานประเภทนี้:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
แค่นั้นแหละ! (ถ้าitem==valในแต่ละการวนซ้ำ 1 จะถูกเพิ่มในตัวสะสมcountตามที่trueจะแก้ไข1)
ในฐานะที่เป็นฟังก์ชั่น:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
หรือไปข้างหน้าและขยายอาร์เรย์ของคุณ:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
มันจะดีกว่าที่จะห่อลงในฟังก์ชั่น:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
นี่คือวิธี ES2017 + ในการรับการนับสำหรับรายการอาร์เรย์ทั้งหมดใน O (N):
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] += 1) : 1;
});
คุณยังสามารถเลือกเรียงลำดับผลลัพธ์:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log (countsSorted) สำหรับอาร์เรย์ตัวอย่างของคุณ:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
ฉันเชื่อว่าสิ่งที่คุณกำลังมองหาคือวิธีการใช้งาน
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' เป็นเงื่อนไขแทนที่ด้วยของคุณเอง
count = arr.filter(elem => elem === 'a').lengthหรือcount = arr.filter(elem => {return elem === 'a'}).length
ฉันเป็นแฟนตัวยงของฟังก์ชันลดอาร์เรย์ของ js
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
ในความเป็นจริงหากคุณต้องการได้รับแฟนซีคุณสามารถสร้างฟังก์ชั่นการนับบนต้นแบบ Array จากนั้นคุณสามารถใช้ซ้ำได้
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
จากนั้นทำ
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
วิธีแก้ปัญหาโดยการสอบถามซ้ำ
function count(arr, value) {
if (arr.length === 1) {
return arr[0] === value ? 1 : 0;
} else {
return (arr.shift() === value ? 1 : 0) + count(arr, value);
}
}
count([1,2,2,3,4,5,2], 2); // 3
filterงานreduceหรือใช้งานง่ายforLoopและมีราคาแพงกว่าเมื่อดูประสิทธิภาพ แต่ก็ยังเป็นวิธีที่ยอดเยี่ยมในการทำแบบเรียกซ้ำ การเปลี่ยนแปลงเพียงอย่างเดียวของฉัน: ฉันแค่คิดว่ามันจะเป็นการดีกว่าที่จะสร้างฟังก์ชั่นและเพิ่มตัวกรองภายในเพื่อคัดลอกอาร์เรย์และหลีกเลี่ยงการกลายพันธุ์ของอาร์เรย์เดิมจากนั้นใช้ฟังก์ชันเรียกซ้ำเป็นฟังก์ชันภายใน
var arrayCount = [1,2,3,2,5,6,2,8];
var co = 0;
function findElement(){
arrayCount.find(function(value, index) {
if(value == 2)
co++;
});
console.log( 'found' + ' ' + co + ' element with value 2');
}
ฉันจะทำอะไรแบบนั้น
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
สร้างวิธีการใหม่สำหรับคลาส Array ในไฟล์ระดับ core และใช้ทั่วโครงการของคุณ
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
ใช้สิ่งนี้ได้ทุกที่ในโครงการของคุณ -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
นี่คือหนึ่งซับใน javascript
(v === 2)ในอาร์เรย์ส่งคืนอาร์เรย์ของค่าและศูนย์[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
3ผลที่ได้คือ
ขึ้นอยู่กับว่าคุณต้องการรันมันอย่างไร:
const reduced = (array, val) => { // self explanatory
return array.filter((element) => element === val).length;
}
console.log(reduced([1, 2, 3, 5, 2, 8, 9, 2], 2));
// 3
const reducer = (array) => { // array to set > set.forEach > map.set
const count = new Map();
const values = new Set(array);
values.forEach((element)=> {
count.set(element, array.filter((arrayElement) => arrayElement === element).length);
});
return count;
}
console.log(reducer([1, 2, 3, 5, 2, 8, 9, 2]));
// Map(6) {1 => 1, 2 => 3, 3 => 1, 5 => 1, 8 => 1, …}
คุณสามารถใช้คุณสมบัติความยาวในอาร์เรย์ JavaScript:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2