Yanıtlar:
Çok basit:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
const count = countItems(array, 2);ve uygulama ayrıntıları içeride tartışılabilir.
[ bu cevap biraz tarihli: düzenlemeleri okuyun ]
Arkadaşlarına merhaba de: mapvefilter ve reduceve forEachve everyvb
(Sadece bazen javascript'te for-loop'ları yazıyorum, çünkü blok seviyesi kapsamı eksiktir, bu nedenle yineleme indeksinizi veya değerinizi yakalamanız veya klonlamanız gerekiyorsa, zaten döngü gövdesi olarak bir işlev kullanmanız gerekir. genel olarak daha verimlidir, ancak bazen bir kapatmaya ihtiyacınız vardır.)
En okunabilir yol:
[....].filter(x => x==2).length
( .filter(function(x){return x==2}).lengthBunun yerine yazabilirdik)
Aşağıdakiler, O (N) yerine daha fazla yer tasarrufu sağlar (O (1)), ancak zaman açısından ne kadar fayda / ceza ödeyebileceğinizden emin değilim (ziyaret ettiğinizden beri sabit bir faktörden fazla değil) her öğe tam olarak bir kez):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
(Bu özel kod parçasını optimize etmeniz gerekirse, bazı tarayıcılarda bir for döngüsü daha hızlı olabilir ... jsperf.com'da bir şeyler test edebilirsiniz.)
Daha sonra zarif olabilir ve bir prototip işlevine dönüştürebilirsiniz:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Bunun gibi:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
Yukarıdaki özellik tanımının içine normal eski for-loop tekniğini de yapıştırabilirsiniz (diğer yanıtlara bakın) (yine, muhtemelen daha hızlı olacaktır).
2017 düzenleme :
Hata! Bu cevap doğru cevaptan daha popüler hale geldi. Aslında, sadece kabul edilen cevabı kullanın. Bu cevap sevimli olsa da, js derleyicileri muhtemelen bu gibi durumları optimize etmez (veya spec nedeniyle yapamaz). Yani gerçekten basit bir döngü yazmalısınız:
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;
}
}
});
Eşitlik kavramını .countStrictEq(...)kullanan bir sürüm tanımlayabilirsiniz ===. Eşitlik kavramı yaptığınız şey için önemli olabilir! (örneğin [1,10,3,'10'].count(10)==2, javascript'teki '4' == 4 gibi sayılar ... dolayısıyla onu çağırır .countEqveya operatörü .countNonstrictkullanır ==.)
Ayrıca collections.Counter, sayımı ilk etapta yapmaktan kaçınmak için kendi çoklu set veri yapınızı (örneğin, python ' ' gibi) kullanmayı düşünün .
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: Yine de, hala işlevsel programlama yolunu (veya Array.prototype'i geçersiz kılmadan tek bir tek satırlık) istiyorsanız, bugünlerde daha tersine yazabilirsiniz [...].filter(x => x==2).length. Performansı önemsiyorsanız, bunun döngüsel olmayan (O (N) zaman) ile asimptotik olarak aynı performans olmasına rağmen, O (N) ekstra bellek (O (1) bellek yerine) gerektirebileceğine dikkat edin. kesinlikle bir ara dizi oluşturun ve daha sonra o ara dizinin elemanlarını sayın.
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. Ardından count(list), listenin bir sayı dizisi olduğunu çağırarak kullanın . const count = (list) => list.filter((x) => x.someProp === 'crazyValue').lengthNesne dizisindeki crazyValue örneklerini saymak için de yapabilirsiniz . Not, bu özellik için tam bir eşleşme.
ES6 JS Güncellemesi:
===Doğru karşılaştırmayı elde etmek için daima üçlü eşitler kullanmanız gerektiğini unutmayın :
// 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'de şu oybirliğiyle Ok işlevi (lambda işlevi):
(x) => {
const k = 2
return k * x
}
tek bir giriş için bu kısa forma basitleştirilebilir:
x => 2 * x
returnzımni olduğu yerde .
2017: Birisi hala soruyla ilgileniyorsa, çözümüm şudur:
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 veya alt çizgi kullanıyorsanız, _.countBy yöntemi, dizideki her değerle anahtarlanan toplamların bir nesnesini sağlar. Yalnızca bir değeri saymanız gerekiyorsa, bunu bir astara dönüştürebilirsiniz:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Bu aynı zamanda sayı dizilerinde de işe yarar. Örneğinizin tek astarı şöyle olacaktır:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Bunu yapmanın en tuhaf yolu:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Nerede:
Benim önerim, bir süre veya döngü için kullanın ;-)
Bir döngü kullanmama genellikle bir yönteme çok süreci teslim anlamına gelmez bir döngü kullanılır.
İşte döngü nefret kodlayıcımızın nefretini bir fiyatla tatmin edebilmesinin bir yolu:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
Dizi yöntemi olarak kullanılabiliyorsa, indexOf işlevini art arda çağırabilir ve her seferinde arama işaretçisini taşıyabilirsiniz.
Bu yeni bir dizi oluşturmaz ve döngü forEach veya filtreden daha hızlıdır.
Bakmak için bir milyon üyeniz varsa bu bir fark yaratabilir.
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- ancak buna dikkat edin veya uygulamanız çift haneli rakamlarla iyi oynamaz.
Filtre gibi dizi işlevlerini kullanan gönderilen çözümlerin çoğu, parametreleştirilmediğinden eksiktir.
Burada sayılacak öğenin çalışma zamanında ayarlanabileceği bir çözüm gider.
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);
Bu yaklaşımın avantajı, örneğin X'den büyük elemanların sayısını saymak için işlevi kolayca değiştirebilmesidir.
Ayrıca azaltma işlevini satır içinde de bildirebilirsiniz
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) ...okunması daha zordur ve sadece avantaj sağlamaz ... (acc, x) => acc += number == 2.... Ben kullanımınızı gibi +=yerine acc + (number == 2)gerçi. Gerçi bir haksız sözdizimi HACK gibi geliyor.
Gerçekten, neden gerekir mapveya filterbunun için?
reducebu tür operasyonlar için "doğdu":
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
bu kadar! ( item==valher yinelemede, çözüleceği countgibi akümülatöre 1 eklenecektir ).true1
İşlev olarak:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Veya devam edin ve dizilerinizi genişletin:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
Fonksiyona sarmak daha iyidir:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
O (N) 'deki tüm dizi öğelerinin sayısını almanın bir ES2017 + yolu:
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] += 1) : 1;
});
İsteğe bağlı olarak çıktıyı da sıralayabilirsiniz:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
Örnek diziniz için console.log (countsSorted):
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Aradığın şeyin fonksiyonel yaklaşım olduğuna inanıyorum
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' koşulu, kendinizinkini değiştirin.
count = arr.filter(elem => elem === 'a').lengthcount = arr.filter(elem => {return elem === 'a'}).length
Ben bir js dizisinin azaltma işlevinin hayranıyım.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
Aslında gerçekten süslemek istiyorsanız, Array prototipinde bir sayım işlevi oluşturabilirsiniz. Sonra tekrar kullanabilirsiniz.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Sonra yap
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Özyineleme ile çözüm
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, reduceya da basit forLoopve aynı zamanda daha pahalı, ancak yine de özyineleme ile yapmanın harika bir yolu. Benim tek değişiklik: Ben sadece bir işlev oluşturmak ve dizi kopyalamak ve orijinal dizinin bir mutasyon önlemek için içine bir filtre eklemek için daha iyi olacağını düşünüyorum, sonra özyinelemeli bir iç işlev olarak kullanın.
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');
}
Böyle bir şey yapardım:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
Temel düzey dosyasında Array sınıfı için yeni bir yöntem oluşturun ve bunu projenizin her yerinde kullanın.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Bunu projenizde herhangi bir yerde kullanın -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Javascript'te bir astar var.
(v === 2)Bir dizi ve sıfırlar dizisi döndürerek dizideki eşleşen değerleri bulun .[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
Sonuç 3.
Nasıl çalıştırmak istediğinize bağlı olarak:
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, …}
Uzunluk özelliğini JavaScript dizisinde kullanabilirsiniz:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2