对于模糊的标题,很多道歉,但我需要详细说明。这是有问题的代码,我在http://ariya.ofilabs.com/2013/07/prime-numbers-factorial-and-fibonacci-series-with-javascript-array.html上阅读过:
function isPrime(i) {
return (i > 1) && Array.apply(0, Array(1 + ~~Math.sqrt(i))).
every(function (x, y) {
console.log(x + ' ' + i % y);
return (y < 2) || (i % y !== 0)
});
}
isPrime(23);
isPrime(19);
isPrime(188);
只是为了好玩,我添加了这些日志,以便我们可以看到一些输出:
undefined NaN
undefined 0
undefined 1
undefined 2
undefined 3
undefined NaN
undefined 0
undefined 1
undefined 1
undefined 3
undefined NaN
undefined 0
undefined 0
这是我第一次见过
apply
和every
,请耐心等待,但我的理解是apply
基本上调用了Array函数,其中第一个参数是其this
和第二个是输出...从来没有人认为这会有用,但是此功能似乎有效,所以...在这里,他们似乎正在创建一个长度等于该数字的平方根的数组。我认为这是有道理的,因为平方根将是所讨论数字的最大可能因数。
好的,因此从这里开始,如果我们要为该数组记录第一个数字,则它看起来像这样:
> var i = 23;
undefined
> Array.apply(0, Array(1 + ~~Math.sqrt(i)));
[ undefined, undefined, undefined, undefined, undefined ]
很好,所以它是五个
undefined
的数组。好的,好的,因此从这里开始,every
方法应该检查该数组中的每个元素是否通过了回调函数测试(或其他测试)。Microsoft文档为
every
方法指定了三个可能的参数:值
指数
数组
因此,在此示例中,
x
是值,即undefined
,而y
是索引。我们的输出同意这一结论。但是,我仍然对嵌套的return语句(如果最低的返回,它的父级也返回吗?),此处的
||
运算符(如果第一个测试通过,是否每个循环都停止了)还是很困惑。这是如何工作的。编辑
日志应使用x而不是y。我的错:
console.log(y + ' ' + i % y); -> console.log(x + ' ' + i % y);
说明
那么,我是怎么遇到这段代码的呢?好吧,当然,检查Java质数的最简单方法是这样的:
public static boolean isPrime(double num) {
for (double i = 2.0; i < sqrt(num); i++) {
if (num % i == 0.0) {
return true;
}
}
return false;
}
或Python
def isPrime(num):
x = 2
isPrime = True
while x < math.sqrt(num):
if num % x == 0:
isPrime = False
break
x = x + 1
return isPrime
或js
function isPrime(n) {
for (var i = 2.0; i < Math.sqrt(n); i++) {
if (n % i === 0.0) {
return false;
}
}
return true;
}
但是说我想检查像
600851475143
这样的数字的最大素数,这些循环方法会花费太长时间,对吗?我认为,正如我们所描述的,这种“ hack”的效率可能更低,因为它使用的是数组而不是整数或浮点数,但即使如此,我仍在寻找一种解决该问题的更有效方法。 最佳答案
那篇文章中的代码基本上是废话。教人们在同时使用黑客的同时编写代码是浪费。是的,黑客有其应有的地位(优化),但教育工作者应展示不依赖于黑客的解决方案。
哈克1
// the 0 isn't even relevant here. it should be null
Array.apply(0, Array(1 + ...))
哈克2
// This is just Math.floor(x), but trying to be clever
~~x
哈克3
// this is an outright sin; totally unreadable code
// I bet most people don't know the binding precedence of % over +
y + ' ' + i % y
// this is evaluated as
y + ' ' + (i % y)
// example
2 + ' ' + (5 % 2) //=> "2 1"
我对嵌套的return语句还是很困惑(如果最低的返回,它的父级也会返回吗?),
否。
return
仅返回语句所在的函数||运算符在这里(如果第一个测试通过,则每个循环都停止吗?)
否。一旦回调返回
Array.prototype.every
,false
将返回false
。如果从未从回调中返回false
,则.every
将返回`true。function isEven(x) { return x % 2 === 0; }
[2,4,5,6].every(isEven); //=> false, stops at the 5
[2,4,6].every(isEven); //=> true
这是
.every
短路的示例[1,2,3,4,5,6].every(x=> {console.log(x, x<4); return x<4;});
// 1 true
// 2 true
// 3 true
// 4 false
//=> false
看看回调返回
false
后如何停止?甚至不评估元素5
和6
。...以及一般的运作方式。
&&
类似于Array.prototype.every
的作品和||
类似于Array.prototype.some
的作品。一旦遇到第一个
&&
,false
将返回false
;换句话说,它期望每个参数都是true
。一旦遇到第一个
||
,true
将返回true
;换句话说,它只希望某些参数为true
。相关:short circuit evaluation
关于javascript - 为什么此JavaScript函数起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37449332/