使用调试器逐行查看代码并检查变量值,你应该能够很快找到问题所在。
如果你想使用 for
循环,可以简化代码,并省略对 0 和 1 的特殊情况处理,同时修复循环条件的顶部:
function isIncreasing(xs) {
var prev, cur;
for (var i = 0; i < xs.length; i++) {
cur = xs[i];
if (i && cur !== prev && cur !== prev + 1) return false;
prev = cur;
}
return true;
}
如果您可以使用ES5数组方法,则可以使用
every
来实现此操作:
[1, 2, 3].every(function(elt, idx, arr) {
var prev = arr[idx - 1];
return !idx || elt === prev || elt === prev + 1;
})
如果您想让您的代码更语义化和易读,请定义一个命名明确的函数:
function sameOrGreater(elt, idx, arr) {
var prev = arr[idx - 1];
return !idx || elt === prev || elt === prev + 1;
}
[1, 2, 3].every(sameOrGreater)
继续这个因式分解,我们可以将解决方案分为两个方面。第一个是看一个值是否与另一个值相同或大于另一个值。第二个是取数组中相邻元素的一对。换句话说,我们希望能够将解决方案写成
pairs(xs).every(sameOrGreater)
sameOrGreater
很简单:
function sameOrGreater(x, y) { return x === y || x === y - 1; }
pairs
可以按照以下方式编写:
function pairs(array) {
return array.slice(1).map(function(elt, idx, arr) {
return [array[idx], elt];
});
}
> pairs([1, 2, 3])
< [[1, 2], [2, 3]]
您可能更喜欢使用生成器编写pairs
:
function* pairs(array) {
let prev;
for (const x of array) {
yield [prev, x];
prev = x;
}
}
或者,我们可以编写一个版本的map
函数,该函数接受一个将被输入一对值的函数,如下所示:
function mapPairs(xs, fn) {
var result = [];
for (var i = 1; i < xs.length); i++) {
result.push(fn(x[i - 1], x[i]));
}
return result;
}
现在我们可以把整个问题写成:
mapPairs(xs, sameOrGreater).every(Boolean)
i <= xs.length - 1
,但应该是i < xs.length - 1
。另外规范似乎不太清楚——例如[1, 2, 3, 5]
没有经过测试,但根据原始表达式,它可能会被禁止使用。 - Ken Y-N