Jawaban:
Sangat sederhana:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);dan detail implementasi dapat diperdebatkan di dalamnya.
[ jawaban ini sedikit bertanggal: baca hasil edit ]
Katakan halo kepada teman-teman Anda: mapdan filterdan reducedan forEachdan everysebagainya.
(Saya hanya sesekali menulis for-loop dalam javascript, karena pelingkupan tingkat blok tidak ada, jadi Anda harus tetap menggunakan fungsi sebagai badan loop jika Anda perlu menangkap atau mengkloning indeks atau nilai iterasi Anda. For-loop lebih efisien secara umum, tetapi kadang-kadang Anda perlu penutupan.)
Cara yang paling mudah dibaca:
[....].filter(x => x==2).length
(Kita bisa menulis .filter(function(x){return x==2}).lengthsebagai gantinya)
Berikut ini lebih hemat ruang (O (1) daripada O (N)), tapi saya tidak yakin berapa banyak manfaat / penalti yang mungkin Anda bayarkan dalam hal waktu (tidak lebih dari faktor konstan sejak Anda mengunjungi setiap elemen tepat sekali):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(Jika Anda perlu mengoptimalkan bagian kode ini, perulangan for mungkin lebih cepat di beberapa peramban ... Anda dapat menguji berbagai hal di jsperf.com.)
Anda kemudian dapat menjadi elegan dan mengubahnya menjadi fungsi prototipe:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Seperti ini:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
Anda juga dapat menempel teknik for-loop lama yang biasa (lihat jawaban lain) di dalam definisi properti di atas (sekali lagi, itu kemungkinan akan jauh lebih cepat).
Sunting 2017 :
Aduh, jawaban ini lebih populer daripada jawaban yang benar. Sebenarnya, gunakan saja jawaban yang diterima. Sementara jawaban ini mungkin lucu, kompiler js mungkin tidak (atau tidak bisa karena spek) mengoptimalkan kasus tersebut. Jadi, Anda harus benar-benar menulis simpel untuk loop:
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;
}
}
});
Anda dapat menentukan versi .countStrictEq(...)yang menggunakan ===gagasan persamaan. Gagasan kesetaraan mungkin penting untuk apa yang Anda lakukan! (misalnya [1,10,3,'10'].count(10)==2, karena angka-angka seperti '4' == 4 dalam javascript ... maka memanggilnya .countEqatau .countNonstrictmenekankan itu menggunakan ==operator.)
Juga pertimbangkan untuk menggunakan struktur data multiset Anda sendiri (misalnya seperti python ' collections.Counter') untuk menghindari keharusan melakukan penghitungan di tempat pertama.
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 {}
}
}
Demo:
> 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: Meskipun, jika Anda masih menginginkan cara pemrograman fungsional (atau pelepasan one-liner tanpa mengesampingkan Array.prototype), Anda dapat menuliskannya dengan lebih singkat saat ini sebagai [...].filter(x => x==2).length. Jika Anda peduli dengan kinerja, perhatikan bahwa sementara ini asimptotik kinerja yang sama dengan waktu for-loop (O (N)), mungkin memerlukan O (N) memori tambahan (bukan memori O (1)) karena akan hampir tentu menghasilkan array perantara dan kemudian menghitung elemen-elemen array menengah itu.
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. Kemudian gunakan dengan memanggil di count(list)mana daftar adalah array angka. Anda juga bisa melakukan const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthuntuk menghitung instance crazyValue dalam array objek. Catatan, ini adalah pencocokan tepat untuk properti.
ES6 Pembaruan ke JS:
Perhatikan bahwa Anda harus selalu menggunakan triple sama dengan: ===untuk mendapatkan perbandingan yang benar:
// 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
Fungsi Panah dengan suara bulat berikut (fungsi lambda) di JS:
(x) => {
const k = 2
return k * x
}
dapat disederhanakan ke formulir ringkas ini untuk satu input:
x => 2 * x
dimana returntersirat.
2017: Jika seseorang masih tertarik dengan pertanyaan itu, solusi saya adalah sebagai berikut:
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);
Jika Anda menggunakan lodash atau garis bawah metode _.countBy akan memberikan objek total agregat yang dikunci oleh setiap nilai dalam array. Anda bisa mengubahnya menjadi satu-liner jika Anda hanya perlu menghitung satu nilai:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Ini juga berfungsi dengan baik pada array angka. Satu-liner untuk contoh Anda adalah:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Cara teraneh yang bisa saya pikirkan untuk melakukan ini adalah:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Dimana:
Saran saya, gunakan sebentar atau untuk loop ;-)
Tidak menggunakan loop biasanya berarti menyerahkan proses ke beberapa metode yang tidak menggunakan loop.
Inilah cara loop kita yang membenci coder dapat memuaskan kebenciannya, dengan harga:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
Anda juga dapat berulang kali memanggil indexOf, jika tersedia sebagai metode array, dan memindahkan pointer pencarian setiap kali.
Ini tidak membuat array baru, dan loop lebih cepat dari forEach atau filter.
Ini bisa membuat perbedaan jika Anda memiliki sejuta anggota untuk melihatnya.
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- meskipun waspadai ini atau implementasi Anda tidak akan bermain bagus dengan dua digit
Sebagian besar solusi yang diposting menggunakan fungsi array seperti filter tidak lengkap karena tidak parameter.
Ini dia solusi untuk menghitung elemen yang bisa diatur pada saat run time.
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);
Keuntungan dari pendekatan ini adalah dapat dengan mudah mengubah fungsi untuk menghitung misalnya jumlah elemen lebih besar dari X.
Anda juga dapat mendeklarasikan fungsi pengurangan sebaris
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) ...lebih sulit untuk dibaca dan tidak memberikan keuntungan lebih dari adil ... (acc, x) => acc += number == 2.... Saya suka penggunaan Anda +=alih-alih acc + (number == 2). Terasa seperti sintaks yang tidak beralasan HACK.
Sungguh, mengapa Anda perlu mapatau filteruntuk ini?
reduce"dilahirkan" untuk operasi semacam ini:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
itu dia! (jika item==valdalam setiap iterasi, maka 1 akan ditambahkan ke akumulator count, seperti yang trueakan diselesaikan 1).
Sebagai fungsi:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Atau, lanjutkan dan rentangkan array Anda:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
Lebih baik membungkusnya menjadi fungsi:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
Berikut adalah cara ES2017 + untuk mendapatkan jumlah semua item array di 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;
});
Anda juga dapat secara opsional mengurutkan output:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log (countsSorted) untuk contoh array Anda:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Saya percaya apa yang Anda cari adalah pendekatan fungsional
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' adalah syaratnya, ganti dengan milikmu.
count = arr.filter(elem => elem === 'a').lengthataucount = arr.filter(elem => {return elem === 'a'}).length
Saya penggemar berat fungsi js array.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
Bahkan jika Anda benar-benar ingin menjadi mewah, Anda dapat membuat fungsi hitungan pada prototipe Array. Maka Anda dapat menggunakannya kembali.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Lalu lakukan
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Solusi dengan rekursi
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, reduceatau yang sederhana forLoop, dan juga, lebih mahal ketika melihat kinerja, tetapi masih cara yang bagus untuk melakukannya dengan rekursi. Satu-satunya perubahan saya adalah: Saya hanya berpikir akan lebih baik untuk membuat fungsi dan menambahkan filter di dalamnya untuk menyalin array dan menghindari mutasi dari array asli, kemudian menggunakan rekursif sebagai fungsi dalam.
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');
}
Saya akan melakukan sesuatu seperti itu:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
Buat metode baru untuk kelas Array dalam file tingkat inti dan gunakan di seluruh proyek Anda.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Gunakan ini di mana saja dalam proyek Anda -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Berikut ini adalah satu liner di javascript.
(v === 2) dalam array, kembalikan array yang dan nol.[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
Hasilnya adalah 3.
Bergantung pada bagaimana Anda ingin menjalankannya:
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, …}
Anda dapat menggunakan properti length dalam array JavaScript:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2