繁体   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