I follow a javascript course and I am stuck with something. We get a website full of excercises and have to make all the test cases turn green.
We have to check if an array is increasing and return true if that is the case.If the next value is the same as the previous the function must also return true. All my test cases return false for some reason? And if I remove the else only one of the test cases is wrong (this one: [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; }
Advertisement
Answer
Walk through your code with the debugger, stopping at interesting lines and examining the values. You should be able to find the problem soon enough.
If you want to use a for
loop, you can simplify your code, and omit the special casing for 0 and 1, while fixing the top of the loop condition:
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; }
If you’re allowed to use ES5 array methods, this can use every
:
[1, 2, 3].every(function(elt, idx, arr) { var prev = arr[idx - 1]; return !idx || elt === prev || elt === prev + 1; })
If you want to make your code more semantic and readable, define a well-named function:
function sameOrGreater(elt, idx, arr) { var prev = arr[idx - 1]; return !idx || elt === prev || elt === prev + 1; } [1, 2, 3].every(sameOrGreater)
To continue with this factoring, we can separate out two aspects of the solution. The first is to see if one value is the same as or one greater than another. The second is to take pairs of adjacent elements in an array. In other words, we would like to be able to write the solution as
pairs(xs).every(sameOrGreater)
sameOrGreater
is easy:
function sameOrGreater(x, y) { return x === y || x === y - 1; }
pairs
can be written as follows:
function pairs(array) { return array.slice(1).map(function(elt, idx, arr) { return [array[idx], elt]; }); } > pairs([1, 2, 3]) < [[1, 2], [2, 3]]
You might prefer to write pairs
using a generator:
function* pairs(array) { let prev; for (const x of array) { yield [prev, x]; prev = x; } }
Alternatively we could write a version of map
which takes a function to which are fed pairs, as follows:
function mapPairs(xs, fn) { var result = []; for (var i = 1; i < xs.length); i++) { result.push(fn(x[i - 1], x[i])); } return result; }
Now we can write the entire problem as
mapPairs(xs, sameOrGreater).every(Boolean)