最近我遇到了一些应该与这些数组匹配的代码,尽管我可能会尝试,但我无法将所有的谜题拼凑在一起以使有意义
validateSequence([1,2,3,4,5,6,7,8,9]) === true
validateSequence([1,2,3,4,5,8,7,8,9]) === false
validateSequence([2,4,6,8,10]) === true
validateSequence([0,2,4,6,8]) === true
validateSequence([1,3,5,7,9]) === true
validateSequence([1,2,4,8,16,32,64]) === false
validateSequence([0,1,1,2,3,5,8,13,21,34]) === false
以下是验证它的代码:
function validateSequence(x) {
return !!x.reduce(function(a, v, i, arr){
return (arr.length - 1 == i) ? a : a + (arr[i+1] - v) + ',';
}, '').match(/^(d+,)1*$/);
}
例如,这两个是什么!!在x.reduce之前,它是如何工作的?
RegExp/^(d+,)1*$/
表示
^
从字符串开始(d+,)
匹配任意数字(0
.9
),后跟逗号,
。记住这一点- 如果
1
与我们在2中看到的完全相同,那么它将匹配后面的所有内容 - 如果我们已经到达String的末尾,则该模式为匹配
接下来,
x.reduce(function(a, v, i, arr){ /*...*/}, '');
- 创建
''
作为初始条件 - 在数组
x
上,使用以下参数迭代调用函数的每个项a
累加器,上一次返回值(或第一次调用的初始条件)v
当前迭代的项目i
当前迭代的索引arr
阵列.reduce
被调用(即x
,.reduce
的this
)
那么return (arr.length - 1 == i) ? a : a + (arr[i+1] - v) + ','
在做什么呢?
让我们把它重写为if..else
,并在中评论正在发生的事情
if (arr.length - 1 == i) // if this is the last item in the array
return a; // return the accumulator (what we generated last invocation)
else // otherwise
return a + // return the accumulator AND
(arr[i + 1] - v) + // the difference between this item and the next item AND
','; // a comma
最后,我们需要了解的最后一点是!!
。这只是转换的简写
- 一个真实的东西(例如任何对象
[]
、非空字符串等)到true
- 错误的东西(例如
null
,RegExp不匹配)与false
这被应用于RegExp的结果,所以它基本上意味着,如果我们找到匹配,则返回true
,否则返回false
。
这解释了,这是一种非常复杂的方法来完成以下
function validateSequence(seq) {
var delta = seq[1] - seq[0],
i;
// some `.length` test here?
for (i = 2; i < seq.length; ++i)
if (seq[i - 1] + delta !== seq[i])
return false;
return true;
}
我不建议使用您提供的方法。
!!
被称为"double-bang"或"not"运算符,用于将对象强制转换为布尔值。看看是什么!!(不是)JavaScript中的运算符?
reduce
是一个枚举器。它将为数组中的每个元素执行一次回调。看见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
函数在数组中循环,只有当数组中的每个连续元素比前一个元素增加相同的整数值时,函数才会返回true。