我有一个数组:

[1, 2, 3, 5, 2, 8, 9, 2]

我想知道数组中有多少个2。

在JavaScript中,没有for循环的最优雅的方法是什么?


非常简单:

var count = 0;
for(var i = 0; i < array.length; ++i){
    if(array[i] == 2)
        count++;
}

[这个答案有点过时了:阅读编辑,在javascript中'equal'的概念是模糊的]

向你的朋友问好:映射,过滤,减少,forEach和every等等。

(我只是偶尔用javascript写for-loops,因为缺少块级别的作用域,所以如果你需要捕获或克隆你的迭代索引或值,你必须使用函数作为循环的主体。for循环通常更有效,但有时你需要一个闭包。)

最易读的方式:

[....].filter(x => x==2).length

(我们可以写。filter(function(x){return x==2})。长度)

以下是更节省空间(O(1)而不是O(N)),但我不确定你可能会在时间方面付出多少好处/惩罚(不超过一个常数因子,因为你访问每个元素正好一次):

[....].reduce((total,x) => (x==2 ? total+1 : total), 0)

或者正如一位评论者好心指出的那样:

[....].reduce((total,x) => total+(x==2), 0)

(如果你需要优化这段特定的代码,在某些浏览器上for循环可能更快……你可以在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循环技术(参见其他答案)(同样,这可能会快得多)。


2017编辑:

哎呀,这个答案比正确答案更受欢迎。实际上,用公认的答案就行了。虽然这个答案可能很可爱,但js编译器可能不会(或由于规范)优化这种情况。所以你应该写一个简单的for循环:

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强调它使用==操作符。)

Caveat: Defining a common name on the prototype should be done with care. It is fine if you control your code, but bad if everyone wants to declare their own [].count function, especially if they behave differently. You may ask yourself "but .count(query) surely sounds quite perfect and canonical"... but consider perhaps you could do something like [].count(x=> someExpr of x). In that case you define functions like countIn(query, container) (under myModuleName.countIn), or something, or [].myModuleName_count().

还可以考虑使用自己的多集数据结构(例如python的'collections.Counter'),以避免首先进行计数。这适用于形式[]的精确匹配。过滤器(x = x = = > ? ?)。长度(最坏情况下O(N)到O(1)),并修改将加快查询形式[].filter(filterFunction)。长度(大约是#total/#duplicate的一个因子)。

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: Though, if you still wanted the functional-programming way (or a throwaway one-liner without overriding Array.prototype), you could write it more tersely nowadays as [...].filter(x => x==2).length. If you care about performance, note that while this is asymptotically the same performance as the for-loop (O(N) time), it may require O(N) extra memory (instead of O(1) memory) because it will almost certainly generate an intermediate array and then count the elements of that intermediate array.


我能想到的最奇怪的方法是:

(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1

地点:

A是数组 N是数组中要计数的数字

我的建议,使用while或for循环;-)


不使用循环通常意味着将进程交给一些使用循环的方法。

这里有一个讨厌循环的编码器可以以一定的代价来满足他的厌恶:

var a=[1, 2, 3, 5, 2, 8, 9, 2];

alert(String(a).replace(/[^2]+/g,'').length);


/*  returned value: (Number)
3
*/

如果indexOf作为数组方法可用,还可以重复调用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
*/

如果您正在使用lodash或下划线_。countBy方法将提供一个由数组中的每个值键定的总计的对象。如果你只需要计算一个值,你可以把它变成一行代码:

_.countBy(['foo', 'foo', 'bar'])['foo']; // 2

这也适用于数字数组。示例中的一行代码是:

_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3

递归解

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)的解决方案都是不完整的,因为它们没有参数化。

这里有一个解决方案,可以在运行时设置要计数的元素。

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的元素的数量。

还可以将reduce函数声明为内联的

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 arrayCount = [1,2,3,2,5,6,2,8]; Var co = 0; 函数findElement () { arrayCount。Find(函数(值,索引){ If (value == 2) 公司+ +; }); Console.log ('found' + ' ' + co + '元素值为2'); }

我会这样做:

var arraycount = [1,2,3,4,5,6,7,8]; 函数 countarr(){ 变量 dd = 0; arrayCount.forEach( function(s){ DD++; }); 控制台.log(dd); }


2017: 如果有人仍然对这个问题感兴趣,我的解决方法如下:

const arrayToCount = [1,2,3,5,2,8,9,2]; const result = arrayToCount。Filter (i => i == 2).length; Console.log('找到的元素数量:' +结果);


你可以在JavaScript数组中使用length属性:

var myarray = [];
var count = myarray.length;//return 0

myarray = [1,2];
count = myarray.length;//return 2

现代JavaScript:

请注意,在JavaScript (JS)中进行比较时,应该始终使用三重=== =。三重等号确保JS的比较在其他语言中表现得像双等号==(有一个例外,见下文)。下面的解决方案展示了如何用函数的方式解决这个问题,这将确保你永远不会出现越界错误:

// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]

// Functional filter with an Arrow function
// Filter all elements equal to 2 and return the length (count)
array.filter(x => x === 2).length  // -> 3

JavaScript中的匿名箭头函数(lambda函数):

(x) => {
   const k = 2
   return k * x
}

对于单个输入,可以简化为这种简洁的形式:

x => 2 * x

这里隐含了返回。

在JS中总是使用三重等号:=== =进行比较,除了检查可空性:if (something == null){},因为它包括检查未定义,如果你只使用双等号,就像在这种情况下。


在核心级别文件中为Array类创建一个新方法,并在整个项目中使用它。

// 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和0组成的数组。 使用减少。将该数组的所有值相加,得到所找到的总数。

[1, 2, 3, 5, 2, 8, 9, 2]
  .map(function(v) {
    return v === 2 ? 1 : 0;
  })
  .reduce((a, b) => a + b, 0);

结果是3。


我相信你们在寻找的是功能方法

    const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
    const count = arr.filter(elem => elem === 'a').length;
    console.log(count); // Prints 3

Elem === 'a'是条件,用你自己的替换它。


为什么需要map或filter呢? Reduce是为这类操作而“诞生”的:

[1、2、3、5、2、8、9、2]。减少((count,2)=>count+(item==val), 0);

就是这样!(如果item==val在每次迭代中,那么1将被添加到累加器计数中,因为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)
}

我是js数组的reduce函数的开始粉丝。

const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)

事实上,如果你真的想要花哨一点,你可以在Array原型上创建一个count函数。然后你就可以重复使用了。

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)

最好把它包装成函数:

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 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, …}

Array.prototype.count =函数(v) { Var c = 0; 对于(设I = 0;I < this.length;我+ +){ If (this[i] === v){ c++; } } 返回c; } Var arr = [1,2,3,5,2,8,9,2]; console.log (arr.count (2));/ / 3


另一种方法使用RegExp

Const list = [1,2,3,5,2,8,9,2] Const d = 2; Const counter = (' ${list.join()}, '。match(new RegExp(' ${d}\\, ', 'g')) || []).length console.log(柜台)

步骤如下

使用逗号连接字符串,记住在连接后添加',',这样当要匹配的值位于数组的末尾时,就不会有不正确的值 匹配数字和逗号组合的出现次数 获取匹配项的长度


你可以使用内置函数Array.filter()

数组中。Filter (x => x === element).length;

Var arr = [1,2,3,5,2,8,9,2]; //数一下arr中有多少个2 Var计数= arr。Filter (x => x == 2).length; console.log(数);


我用这个:

函数countElement(数组,元素){ 令tot = 0; For (var el of array) { If (el == element) { 合计+ +; } } 返回合计; } var arr =(“a”、“b”、“a”,“c”,“d”,“一个”,“e”,“f”,“a”); “a”console.log (countElement (arr));/ / 4


一行程序功能

const countBy = (a,f)=>a.reduce((p,v,i,x)=>p+!!f(v,i,x), 0)
countBy([1,2,3,4,5], v=>v%2===0) // 2

有很多方法可以找到答案。我认为最简单的方法是使用es6中引入的数组过滤器方法。

function itemCount(array, item) {
    return array.filter(element => element === item).length
}

const myArray = [1,3,5,7,1,2,3,4,5,1,9,0,1]
const items = itemCount(myArray, 1)
console.log(items)

我相信您可以使用JavaScript的新Set数组方法来拥有唯一的值。

例子:

var arr = [1, 2, 3, 5, 2, 8, 9, 2]
var set = new Set(arr);
 
console.log(set);

// 1,2,3,5,8,9。我们得到唯一的值作为输出。


一些更普通和现代的东西(2022年):

import {pipe, count} from 'iter-ops';

const arr = [1, 2, 3, 5, 2, 8, 9, 2];

const n = pipe(arr, count(a => a === 2)).first; //=> 3

这样做的好处是:

它不需要创建一个新的数组,所以它是内存高效的 对于任何Iterable和AsyncIterable都是一样的