【问题标题】:Use reduce() method to find a skipped number in an array of consecutive numbers使用 reduce() 方法在连续数字数组中查找跳过的数字
【发布时间】:2016-10-11 06:09:58
【问题描述】:

我正在尝试使用reduce() 方法在一组(有时几乎是)连续数字中找到一个跳过(缺失)的数字。最多只会丢失一个数字。 这是我的代码笔: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

【问题讨论】:

  • 既然你有一个“基本情况”,你可以用递归(甚至用一个while循环)来做(我认为效率更高)。
  • 如果缺少一个以上的数字会发生什么,例如[1, 4][1, 3, 5]
  • 在这个任务中保证它只会丢失 1 个数字。

标签: javascript arrays loops numbers reduce


【解决方案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;
       }
   }
}

【讨论】:

  • developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 上的 reduce() 方法的文档说“如果没有提供初始值,那么 previousValue 将等于数组中的第一个值,而 currentValue 将等于第二个。 '所以我假设在第一个循环中prev 将等于 1,curr 将等于 2。你认为不是这样吗?
  • 啊,打错字了。但你是对的,在第一个循环中,它将是1, 2。但是第一个循环的返回值将是undefined,所以在第二个循环中它将有参数undefined, 3。我将修改我的答案以纠正错字。
  • 请恢复您最近删除的答案。没有人可以这样命令你。您的答案对 OP 来说更好,也不会令人困惑
【解决方案2】:

你应该在这里使用for循环而不是reduce

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]));

【讨论】:

    【解决方案3】:

    我会按如下方式完成这项工作;

    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);

    注意:void 0 在 JS 中是一个非常安全的 undefined 值。上面的代码将改变测试的数组。如果您想保持已测试的数组原样,您可能更喜欢像 a1.slice().reduce... 这样调用。

    【讨论】:

    • Redu,我正在做进一步的测试,实际上该解决方案不适用于不是从 1 开始的数组。例如:findMissing([2,4,5,6,7]) 你知道如何解决吗?是否可以使用reduce() 方法?
    • @Piotr Berebecki 您现在可以检查一下吗?
    • 你是真正的JS忍者!这两个加号在这种情况下有什么作用?我只知道将它们用于增量(例如i++
    • @Piotr Berebecki 感谢 Piotr,但它非常基本,但看起来有点神秘。我已将代码更正为更易读的形式。实际上,正如您所说,如果遇到不规则行,它会增加 a[0]
    【解决方案4】:

    正如我在 cmets 中所说,如果您正在寻找效率,您可以使用递归来实现:

    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];
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 2017-05-23
      相关资源
      最近更新 更多