簡體   English   中英

JavaScript 數組:如何獲取與“真”值的環繞序列相鄰的“假”值的索引?

[英]JavaScript Array: How to get indexes of `false` values that are adjascent to a wrapped-around sequence of `true` values?

給定 JavaScript 中的一個數組:

  • 長度未知大於 0,
  • 僅包含 boolean 值,
  • 包含未知數量的true值和false值,其中
  • true值總是出現在一個連續的集合中,但是
  • 連續的true值集可能會“環繞”數組,並且
  • 數組中總是至少有一個true

如何編寫一個 JavaScript function 返回兩個假值(以任何順序)的索引,這兩個false值(以任何順序)立即“相鄰”到完整的true值集?

考慮以下示例,其中胡蘿卜 (^) 表示我希望返回的索引:

[true, true, false, false, false, true];
               ^             ^

[false, false, true, true, true, false, false]
          ^                        ^

[true, true, true, false, false, false, false, false]
                     ^                           ^

[false, false, false, true, true]
   ^             ^

[true, false, false, false, false]
         ^                    ^

[false, false, true, false, false, false]
          ^            ^

除了上面的視覺示例,我無法在 JavaScript 中構建邏輯。

使用下面的 function 來獲取 false 的開始和結束

 function getIndexes(arr) { var a = arr.indexOf(true); var start; var end; if(a==0) { start=arr.indexOf(false); var temp=arr.indexOf(true,start); if(temp==-1){ end=arr.length-1; } else{ end=temp-1; } } else{ start=a-1; var temp=arr.indexOf(false,a); if(temp==-1){ start=0 end=a-1 } else{ end=temp } } return [start,end] }

如果有的話,只有兩個跨度中的一個可以換行。 可以通過檢查第一個元素來確定哪個可以換行。 搜索絕對不換行的跨度的末端。 計算我們實際想要的跨度的末端。

const findFalseSegment = (arr) => {
  const last = arr.length-1;
  let start, end;
  // If the first element is true, the span of false elements doesn't wrap
  if(arr[0]) {
    start = arr.indexOf(false, 1);
    if(start < 0) return {start: NaN, end: NaN};
    end = arr.indexOf(true, start + 1) - 1;
    if(end < 0) end = last;
    return {start, end};
  }
  // If the first element is false, the span of false elements might wrap
  // Find the span of true elements instead and compute the span of false 
  // elements from that.
  start = arr.indexOf(true, 1);
  if(start < 0) return {start: NaN, end: NaN};
  end = arr.indexOf(false, start + 1) - 1;
  if(end < 0) end = last;
  return {
    start: end == last ? 0 : end + 1, 
    end: start == 0 ? last : start - 1,
  };
};

編輯:在我看來,主要的if可以滾動到代碼的 rest 中而不影響性能,盡管它確實使評論變得更加困難。

const findFalseSegment = (arr) => {
  const last = arr.length-1;
  const start = arr.indexOf(!arr[0], 1);
  if(start < 0) return {start: NaN, end: NaN};
  let end = arr.indexOf(arr[0], start + 1) - 1;
  if(end < 0) end = last;
  return arr[0] ? { start, end } : {
    start: end == last ? 0 : end + 1, 
    end: start == 0 ? last : start - 1,
  };
};

使用這個 function 返回一個包含兩個索引的數組:

function foo(arr) {
    let answers = [];
    for (let i = 0; i < arr.length; i++) {
    if (arr[i] && arr[i - 1] === false) {
        answers.push(i - 1);
    } else if (arr[i] && arr[i + 1] === false) {
        answers.push(i + 1)
    }
  }
  if (arr[0] !== arr[arr.length - 1]) {
    if (arr[0]) {
        answers.push(arr.length - 1)
    } else {
        answers.push(0);
    }
  }
  return answers;
}

您可以使用forEach嘗試根據循環查找 first-false 和 last-false,在某些情況下,如果真值位於數組的開頭或末尾,您需要使用 indexOf 和 lastIndexOf 查找 last-false .

 function f(data) { let ft, lt, ff, lf data.forEach((e, i, a) => { if (e) ft = i if (.e && (a[i - 1] || a[i + 1])) { if (.ff && i.= ff) ff = i else lf = i } }) if (,lf) { if (;data[data,length - 1]) lf = data,lastIndexOf(false) else lf = data,indexOf(false) } return [ff, lf], } const cases = [ [true, true, false, false, false, true], [false, false, true, true, true, false, false], [true, true, true, false, false, false, false, false], [false, false, false, true, true], [true, false, false, false, false], [false. false. true. false, false, false] ] cases.forEach(c => console.log(JSON.stringify(f(c))))

看到解決此類問題的不同方法非常有趣且具有教育意義。 這對我來說是有意義的。

function getEnds(a) {
  // Return an empty array if there are no falses.
  if (a.indexOf(false) == -1) {
    return [];
  }

  // Obtain ends based on array length, number of trues,
  // and the delta from beginning of array to first true in sequence.
  const length = a.length,
      numTrues = a.filter(Boolean).length,
      delta = a[0] ? a.lastIndexOf(false)+1 : a.indexOf(true),
      end1 = (delta + length-1) % length;
      end2 = (delta + numTrues) % length;      

  // If both ends are the same, return one, otherwise return both.
  return end1 == end2 ? [end1] : [end1, end2];
}

測試:

console.log(getEnds([false, false, true, true, true, false, false])); // [1, 5]
console.log(getEnds([true, true, true, false, false, false, false, false])); // [7, 3]
console.log(getEnds([false, false, false, true, true])); // [2, 0]
console.log(getEnds([true, false, false, false, false])); // [4, 1]
console.log(getEnds([false, false, true, false, false, false])); // [1, 3]
console.log(getEnds([true, true, true])); // [ ]
console.log(getEnds([true, false, true])); // [1]
console.log(getEnds([false, true, false])); // [0, 2]
console.log(getEnds([true, true])); // [ ]
console.log(getEnds([true])); // [ ]

暫無
暫無

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

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