[英]JavaScript Array: How to get indexes of `false` values that are adjascent to a wrapped-around sequence of `true` values?
Given an array in JavaScript that:给定 JavaScript 中的一个数组:
true
and false
values, where包含未知数量的true
值和false
值,其中true
values always occur in one continuous set, but true
值总是出现在一个连续的集合中,但是true
values may "wrap around" the array, and连续的true
值集可能会“环绕”数组,并且true
in the array数组中总是至少有一个true
how does one write a JavaScript function that returns the indexes of the two false
values (in any order) that are immediately "adjacent" to the full set of true
values?如何编写一个 JavaScript function 返回两个假值(以任何顺序)的索引,这两个false
值(以任何顺序)立即“相邻”到完整的true
值集?
Consider the following examples, where carrots (^) denote the indexes I would like returned:考虑以下示例,其中胡萝卜 (^) 表示我希望返回的索引:
[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]
^ ^
Apart from the visual examples above, I've been unable to construct the logic within JavaScript.除了上面的视觉示例,我无法在 JavaScript 中构建逻辑。
Use below function to get start and end of false使用下面的 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] }
Only one of the two spans can wrap if any does.如果有的话,只有两个跨度中的一个可以换行。 Which one might wrap can be determined by checking the first element.可以通过检查第一个元素来确定哪个可以换行。 Search for the ends of the span that definitely doesn't wrap.搜索绝对不换行的跨度的末端。 Compute the ends of the span we actually want from that.计算我们实际想要的跨度的末端。
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,
};
};
Edit: It occurred to me that the main if
can be rolled into the rest of the code without impacting performance though it does make it more difficult to comment.编辑:在我看来,主要的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,
};
};
Use this function which returns an array with the two indexes:使用这个 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;
}
You could use forEach
to try to find first-false and last-false based on loop and in some cases where the true values are either on the start or on the end of the array you need to find last-false by using indexOf and lastIndexOf.您可以使用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))))
It's been very interesting and educational to see the different ways to solve such a problem.看到解决此类问题的不同方法非常有趣且具有教育意义。 Here's what made sense to me.这对我来说是有意义的。
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];
}
Tests:测试:
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.