我遵循javascript课程而且我遇到了困难。我们得到一个充满练习的网站,并且必须让所有的测试用例变成绿色。
我们必须检查一个数组是否在增加,如果是这种情况,则返回true。如果下一个值与前一个值相同,则该函数也必须返回true。由于某些原因,我的所有测试用例都返回false如果我删除其他只有一个测试用例是错误的(这一个:[0,1,2,3,4,5,0])。 Here are the test cases.
function isIncreasing(xs) {
var result = false;
if (xs.length == 1 || xs.length === 0) {
return true;
}
for (var i = 0; i <= xs.length - 1; i++) {
if (xs[i] == xs[i + 1] - 1 || xs[i] == xs[i + 1]) {
result = true;
}
else return false;
}
return result;
}
答案 0 :(得分:1)
您的循环尝试访问上一次迭代(i == xs.length - 1
然后xs[i+1]
)数组边界之外的元素。更简洁的方法是从第二个elem开始,然后与之前的,而不是下一个进行比较。
function isIncreasing(xs) {
for (var i = 1; i < xs.length; i++) {
if (xs[i] !== xs[i - 1] && xs[i] != xs[i - 1] + 1) {
return false;
}
}
return true;
}
console.log(isIncreasing([]));
console.log(isIncreasing([1]));
console.log(isIncreasing([1,2,3,4,4,5]));
console.log(isIncreasing([0,1,2,3,4,5,0]))
还要注意如何简化您的功能(长度检查和实际上不需要结果变量)。
答案 1 :(得分:0)
使用调试器遍历代码,停留在有趣的行并检查值。你应该能够尽快找到问题。
如果你想使用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)
答案 2 :(得分:0)
由于没有答案正在使用Array.prototype.reduce
,我认为这是完美的选择,因此下面是使用reduce
的解决方案:
var arrayIsAscending = [-1, 13, 14].reduce((outcome, value, index, array) => {
if (!outcome) return false // if at least one item failed, this will always return false
if (index === 0) return true // first item cannot be checked against a previous item
return value > array[index-1]
}, true)
console.log(arrayIsAscending)
当然,可以还原传递给reduce的函数并为其指定名称。
答案 3 :(得分:0)
isIncreasing = (array) => {
for(i = 0; i <= array.length; i++){
if(array[i] < array[i + 1]) {}
else if (i <= array.length && array[i] < array[i + 1]) return true;
else return false;
}
}
此代码使用for循环来迭代数组的索引,并使用比其更高的索引来检查数组的索引是否更大。因为return
停止了函数的执行。我放置了一个if
语句,检查它是否在递增,如果为true,则不执行任何操作,但如果不为true,则停止函数执行,因为它没有递增。 else if
仅检查它是否到达最后一个索引而没有错误。
答案 4 :(得分:0)
也许我们可以这样调整:
var isIncreasing = (arr) => {
return (
arr.every((v, i) => i === 0 || v >= arr[i - 1])
);
};
console.log(isIncreasing([]));
console.log(isIncreasing([0]));
console.log(isIncreasing([1, 0]));
console.log(isIncreasing([1, 1, 1]));
console.log(isIncreasing([1, 1, 2, 3, 3]));
console.log(isIncreasing([0, 1, 2, 3, 4, 5, 0]))