如何获取与 javascript 数组中的谓词匹配的元素计数?

问题描述

假设我们要计算 javascript 数组中的 NaN。我们可以使用

let arr = [...Array(100)].map( (a,i) => i %10==0 ?  NaN : i )
console.log(arr)

> [NaN,1,2,3,4,5,6,7,8,9,NaN,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,51,52,53,54,55,56,57,58,59,61,62,63,64,65,66,67,68,69,71,72,73,74,75,76,77,78,79,81,82,83,84,85,86,87,88,89,91,92,93,94,95,96,97,98,99]

let nans = arr.map( aa => isNaN(aa) ? 1 : 0).reduce((acc,a) => acc+a)
console.log(nans)
> 10

这确实有效......但每次记住 reduce() 机制有点挑战。通过应用谓词是否有更简洁的构造:

arr.count( a => isNan(a))

解决方法

您可以只有一个 .reduce,其中累加器是到目前为止找到的 NaN 的数量:

const arr = [...Array(100)].map( (a,i) => i %10==0 ?  NaN : i );
const nans = arr.reduce((a,item) => a + isNaN(item),0);
console.log(nans);

,

您可以过滤掉不是 NaN 的元素。

arr.filter(isNaN).length
//or
arr.filter(function(it){ return isNaN(it); }).length
,

或者 while 以获得更大的...

const arr = [...Array(1e6)].map((a,i) => i % 10 == 0 ? NaN : i);

let
  i = arr.length,nans = 0;
  
while (i--) {
  nans += isNaN(arr[i]);
}

console.log(nans.toExponential());

const arr = [...Array(100)].map((a,i) => i % 10 == 0 ? NaN : i);

const count = (arr,predicate) => {
  let c = 0,i = arr.length;
  while (i--) c += predicate(arr[i]);
  return c
};

const
  nans = count(arr,x => isNaN(x)),sevens = count(arr,x => x % 7 === 0);

console.log(`nans: ${nans},sevens: ${sevens}`);

,

forEach 循环代替 map 和 reduce

const nanCount = (arr,count = 0) => (
  arr.forEach((num) => (count += isNaN(num))),count
);


const arr = [NaN,1,3,NaN];
console.log(nanCount(arr));