簡體   English   中英

使用 reduce() 方法在連續數字數組中查找跳過的數字

[英]Use reduce() method to find a skipped number in an array of consecutive numbers

我正在嘗試使用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

您的 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;
       }
   }
}

而不是 reduce 你應該在這里使用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]));

我將按以下方式完成這項工作;

 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...

正如我在評論中所說,如果您正在尋找效率,您可以通過遞歸來做到這一點:

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];
}
 var findMissing = function (list) {  
           var expected_sum = (list[0] + list[list.length - 1]) * (list.length + 1) / 2;
           var sum = list.reduce((a,b)=>a+b);
           return expected_sum - sum;
         }
          
          console.log(findMissing([-5,-1,1,3,5,7,9,11]))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM