我有一个数组:

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

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

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


当前回答

有很多方法可以找到答案。我认为最简单的方法是使用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)

其他回答

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

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

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

_.countBy([1, 2, 3, 5, 2, 8, 9, 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 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
*/

最好把它包装成函数:

let countNumber = (array,specificNumber) => {
    return array.filter(n => n == specificNumber).length
}

countNumber([1,2,3,4,5],3) // returns 1

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

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

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