I'm trying to use the reduce()
method to find one skipped (missing) number in an array of (sometimes almost) consecutive numbers. Only one number will be missing at most.
This is my codepen: http://codepen.io/PiotrBerebecki/pen/zBrRVd
例如,
findMissing([1,2,3,5])
应返回4
findMissing([1,2,3,4])
应该返回undefined
findMissing([2,3,4,6])
应该返回5
findMissing([2,4,5,6])
应返回3
如果确实有一个跳过的数字,我开发的代码似乎工作正常。但如果所有数字都存在,它会返回不需要的值。你知道怎么解决吗?
我的JS代码:
function findMissing(arr) {
return arr.reduce(function(prev, curr) {
if (curr - prev !== 1) {
return curr - 1;
}
});
}
// This should return 4, and it indeed returns 4
console.log( findMissing([1,2,3,5]) );
// This should return 'undefined', but it returns 3
console.log( findMissing([1,2,3,4]) );
// This should return 5, and it indeed returns 5
console.log( findMissing([2,3,4,6]) );
更新1:
根据以下答案,以下代码使用reduce()
方法提供了所需的结果:
// ****SOLUTION:****
function findMissing2(arr) {
return arr.reduce(function(prev, curr, index, array) {
if (curr === index + array[0]) {
return prev;
} else {
return index + array[0]++;
}
}, void 0);
}
console.log( findMissing2([1,2,3,4]) ); // Undefined
console.log( findMissing2([1,2,3,5]) ); // 4
console.log( findMissing3([2,3,4,6]) ); // 5
console.log( findMissing2([2,3,4,5]) ); // Undefined
console.log( findMissing2([2,4,5,6]) ); // 3
答案 0 :(得分:1)
您的reduce闭包/回调函数需要返回在下一次迭代中用作下一个prev
的值。
因此,在第二个示例中,第一次迭代返回undefined
,因为它没有进入if
块。第二次迭代传递undefined, 3
的参数,其中undefined - 3 !== 1
,所以它返回2.
这会传播你的迭代,直到它返回3.
因此,我很难想到一种方法可以调整reduce
函数来纠正这个问题。
也许使用简单的for
循环可能会更强大一些?
function findMissing(arr) {
for(var i = 1; i < arr.length; i++) {
if(arr[i] - arr[i-1] !== 1) {
return arr[i]-1;
}
}
}
答案 1 :(得分:1)
而不是简化,你应该在这里使用for
循环
function findMissing(arr) {
var r = [];
for (var i = arr[0]; i <= arr[arr.length - 1]; i++) {
if (arr.indexOf(i) == -1) r.push(i);
}
return r;
}
console.log(findMissing([1, 2, 3, 5]));
console.log(findMissing([1, 3, 6]));
console.log(findMissing([10, 13, 16]));
答案 2 :(得分:1)
我会按照以下方式完成这项工作;
var a1 = [1,2,3,5],
a2 = [2,3,4,5],
a3 = [2,4,5,6],
res1 = a1.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0),
res2 = a2.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0),
res3 = a3.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0);
console.log(res1);
console.log(res2);
console.log(res3);
&#13;
注意:void 0
是JS中非常安全的undefined
值。上面的代码将改变测试的数组。如果要保持测试的数组不变,您可能更愿意像a1.slice().reduce...
那样调用。
答案 3 :(得分:1)
正如我在评论中所说,如果你正在寻找效率,你可以通过递归来实现:
function findMissing(arr) {
if (arr.length === 1) return;
if(arr[1] - arr[0] !== 1){
return arr[0];
}
else{
return findMissing(arr.slice(1,arr.length));
}
}
甚至使用while循环:
function findMissing(arr) {
var i = 0;
while (arr[i+1] - arr[i] === 1) {
i++;
}
if (i < arr.length-1) return arr[i];
}