我有一个包含64个索引的数字数组(它是画布图像数据)。
我想知道我的数组是否仅包含零或零以外的其他任何内容。
我们可以在第一次遇到任何大于零的数字时返回一个布尔值(即使最后一个索引为非零且所有其他索引都为零,我们应该返回true)。
确定此问题的最有效方法是什么?
当然,我们可以遍历我们的数组(专注于testImageData
函数):
// Setup
var imgData = {
data: new Array(64)
};
imgData.data.fill(0);
// Set last pixel to black
imgData.data[imgData.data.length - 1] = 255;
// The part in question...
function testImageData(img_data) {
var retval = false;
for (var i = 0; i < img_data.data.length; i++) {
if (img_data.data[i] > 0) {
retval = true;
break;
}
}
return retval;
}
var result = testImageData(imgData);
...但如果我的阵列更大,这可能需要一段时间。
是否有更有效的方法来测试数组中的任何索引是否大于零?
我对使用lodash的答案持开放态度,尽管我在这个项目中没有使用lodash。我希望答案是原生JavaScript,ES5或ES6。我将忽略任何jQuery答案,只是说......
更新
我设置了一个测试,用于检查数组中非零值的各种方法,结果很有趣。
注意,Array.some
测试比使用for (index)
甚至for-in
要慢得多。当然,最快的是for(index)
for(let i = 0; i&lt; arr.length; i ++)... 。
你应该注意我还测试了一个Regex解决方案,只是为了看看它是如何比较的。如果你运行测试,你会发现Regex解决方案要慢得多(不奇怪),但仍然非常有趣。
我想看看是否有可以使用按位运算符完成的解决方案。如果您有这种感觉,我希望看到您的方法。
答案 0 :(得分:1)
您的for
循环是使用Windows 10的Chrome 64上的最快方式。
我已针对其他两个选项here is the link to the test进行了测试,因此您可以在您的环境中运行它们。
我的结果是:
// 10776 operations per second (the best)
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== 0) {
break
}
}
// 4131 operations per second
for (const n of arr) {
if (n !== 0) {
break
}
}
// 821 operations per second (the worst)
arr.some(x => x)
答案 1 :(得分:0)
没有比循环遍历数组中每个元素更快的方法。逻辑上在最坏的情况下,阵列中的最后一个像素是黑色的,因此您必须检查所有这些像素。因此,最佳算法只能具有O(n)运行时。你能做的最好的事情就是写一个循环,在找到一个非白色像素时提前中断。