在数组中查找上边界和下边界



我正在尝试获取数组中numeric值的上下边界。

const boundaries = [15, 30, 45, 60, 75, 90];
const age = 22;

对于上面的例子,结果应该是:

[15, 30]

例如,如果该值是一个边界,则它将成为结果数组中的lower值。如果它是最大边界或以上,它应该成为最大值。

示例结果:

15 => [15, 30]
22 => [15, 30]
30 => [30, 45]
90 => [90]

我通过阵列尝试了CCD_ 3,并且如果CCD_;return boundary。然后filter找出边界并计算索引,但这感觉不是实现这一点的正确方法。

const boundaries = [15, 30, 45, 60, 75, 90];
const age = 22;
// get all lower values
const allLower = boundaries.map((b) => age > b ? b : null).filter(x => x);
const lower = allLower[allLower.length - 1]; // get lowest
const upper = boundaries[boundaries.indexOf(lower) + 1]; // get next
const result = [lower, upper]; // form result
console.log(result);

shorter/better/more reliable的方法吗?

为什么要使用索引?如果boundaries数组没有排序怎么办?将列表筛选为allLowerallUpper(包含低于和高于阈值的值(,然后在生成的数组上使用minmax,这不是更容易吗?


样本代码:

const boundaries = [15, 30, 45, 60, 75, 90];
const age = 22;
const allLower = boundaries.filter(x => x < age);
const allUpper = boundaries.filter(x => x > age);
const lowerBound = Math.max(...allLower);
const upperBound = Math.min(...allUpper);

看起来是reduce:的一个很好的用例

const boundaries = [15, 30, 45, 60, 75, 90];

for (let search of [1, 22, 30, 90, 100]) {
let [low, upr] = boundaries.reduce(([low, upr], x) =>
[
x <= search ? Math.max(low, x) : low,
x >  search ? Math.min(upr, x) : upr,
],
[-Infinity, +Infinity]
)
console.log(low, '<=', search, '<', upr)
}

这不需要对边界进行排序。如果它们总是这样,您可以考虑二进制搜索来定位下界。

看起来纯for循环可能会帮助您;(

function getBounds(age) {
for (let i = 0; i < boundaries.length; i++) {
if (boundaries[i] <= age && (boundaries[i + 1] ?? Infinity) > age) {
return boundaries.slice(i, i + 2);
}
}
}

您可以检查上一个值和下一个值并过滤数组。

const
getLowerUpper = (array, pivot) => array
.filter((v, i, { [i - 1]: prev, [i + 1]: next }) =>
v <= pivot && next > pivot ||
prev <= pivot && v >= pivot ||
prev === undefined && next > pivot ||
prev < pivot && next === undefined
),
boundaries = [15, 30, 45, 60, 75, 90];
console.log(...getLowerUpper(boundaries, 22));  // between
console.log(...getLowerUpper(boundaries, 30));  // direct and next
console.log(...getLowerUpper(boundaries, 10));  // lowest
console.log(...getLowerUpper(boundaries, 15));  // direct and next
console.log(...getLowerUpper(boundaries, 90));  // highest
console.log(...getLowerUpper(boundaries, 100)); // highest

您可以减少数组,如下所示:

const boundaries = [15, 30, 45, 60, 75, 90];
const getResult = (array, target) => {
if (target < array[0] || target > array[array.length - 1]) {
return [];
}
return array.reduce((a, c) => {
if (c <= target) {
a[0] = c;
} else if (c > target && (!a[1] || c < a[a.length - 1])) {
a[a.length] = c;
}
return a;
}, []);
}
console.log(getResult(boundaries, 22));
console.log(getResult(boundaries, 15));
console.log(getResult(boundaries, 30));
console.log(getResult(boundaries, 90));
console.log(getResult(boundaries, 14));
console.log(getResult(boundaries, 91));

最新更新