数组中空值的计数

13

给定一个数组:

var arr = [1,,2,5,6,,4,5,6,,];

计算一个数组中有多少个空值:(长度 - 删除所有空值后的长度)

var empties = arr.length - arr.filter(function(x){ return true }).length;

// return 3

或者像这样

arr.empties = arr.length;
arr.forEach(function(x){ arr.empties--  });

// arr.empties returns 3

这是最好的方法吗?还是我漏掉了什么?


我正在尝试找到可能的最小代码片段。 - vsync
1
arr.length - arr.filter(Number).length - vsync
3个回答

37

根据您对另一个答案的评论,看起来您想要最短的方法。那么,您可以考虑一下自己示例的变体:

var empties = arr.length - arr.filter(String).length;
你所做的就是传递一个本地函数而不是匿名函数,节省了一些宝贵的字节。任何本地构造函数或函数都可以,只要它不返回布尔值。
你需要更具体地说明你认为什么是“最佳方法”。例如,某些方法比其他方法性能更好,某些方法更简洁,某些方法具有更好的兼容性。
你在帖子中提到的解决方案需要浏览器与ECMAScript第5版规范兼容,因此在一些旧版本浏览器(即IE8及以下版本)中无法使用。
“最佳”的全面方法是一个简单的循环。它不像你的方法那样简洁,但毫无疑问它将是最快和最兼容的:
var arr = [1,,2,5,6,,4,5,6,,], count = 0, i = arr.length;

while (i--) {
    if (typeof arr[i] === "undefined")
        count++;
}

使用循环优化(使用while和递减速度比for快)。

另一种方法是对数组进行排序,使得undefined项都在末尾,并使用循环向后迭代:

var arr = [1,,2,5,6,,4,5,6,,], count = 0;
arr.sort();
while (typeof arr.pop() === "undefined") count++;

alert(count); 
//-> 3

这种方法将修改原始数组并删除可能不是您想要的项目。 但是,在非常大的数组上,它可能会更快。

性能测试套件
http://jsperf.com/count-undefined-array-elements


你的第一个方法不起作用了...为什么是arr.length - 1而不是只有arr.length - vsync
@vsync:它最初是一个for循环。当我更改它时,忘记删除-1。已修复 :-)在看到您对@stecb答案的评论后,我还添加了自己方法的较短版本。 - Andy E
@vsync: 如果你想让它更小,可以尝试在http://codegolf.stackexchange.com上提问。如果你这样做了,就告诉我,我会在那里发布我的答案。 - Andy E

5

我认为这看起来不错。

你也可以这样做:

var empties = arr.reduce(function(x, y){ return x-1; }, arr.length);

另外,如果您不介意对数组进行排序,您可能会获得更好的性能:

arr.sort();
for (var j=arr.length-1; j > 0 && arr[j] === undefined; j--) {}
var empties = arr.length-j-1;

1
谢谢--我喜欢reduce--我认为它被低估了 - Brett Zamir
你甚至可以在没有使用'y'参数的情况下进行减少操作,因为它根本没有被使用。 - vsync
是的 - 我只是为了展示reduce有什么可用的冗余而将其放置。 - Brett Zamir

1

或者,不使用js 1.6的filter/foreach,你可以自己这样循环它:

var arr = [1,,2,5,6,,4,5,6,,];
var emptyElems = 0;
for(var i=0, l = arr.length; i < l; i++){
    emptyLength += (arr[i] === undefined) ? 1 : 0;
}

alert(emptyElems); //alerts 3

是的,当然可以,但我正在尝试找到最小的代码片段,无论兼容性如何。 - vsync
哦,我不知道“smallest” :) - stecb
1
emptyElems != emptyLength - luksch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接