【问题标题】:Get closest index of value in array获取数组中最接近的值索引
【发布时间】:2019-08-12 17:34:12
【问题描述】:

我尝试在数组中获取最接近的值索引。索引必须最接近 向上值,并且不依赖于顺序 - asc 或 desc

我目前正在使用返回最接近向上索引的函数,但数组必须是 asc(缺少 desc)。

function closestIndex(value, arr, from, to) {
  from = (typeof from !== 'undefined') ? from : 0;
  to = (typeof to !== 'undefined') ? to : arr.length;
  
  if (from >= to) {
    return to - 1;
  }
  
  var mid = Math.floor((from + to) / 2);
  if (arr[mid] > value) {
    return closestIndex(value, arr, from, mid);
  }
  
  return closestIndex(value, arr, mid + 1, to);
}

var arr = [10, 15, 20, 50, 100];
console.log(closestIndex(8, arr)); //index: -1
console.log(closestIndex(10, arr)); //index: 0
console.log(closestIndex(14, arr)); //index: 0
console.log(closestIndex(1000, arr)); //index: 4

我应该收到这些值:

//var arr = [100,50,20,15,10]; //same, just reversed values
//val: 8 = idx: 4
//val: 10 = idx: 4
//val: 14 = idx: 3
//val: 1000 = idx: -1

【问题讨论】:

  • 当数组中的索引5 处没有元素时,为什么5 是一个结果?
  • 基于什么你认为一个值(来自数组)接近输入值?
  • 而二分查找只适用于已排序的数据集,如果有时升序有时降序,则未排序。
  • @Paulpro 如果你注意到了,整行移动 1 - 如果值小于第一个值,它返回 0 insted of -1 - 仅用于“我的”需要

标签: javascript arrays closest


【解决方案1】:

如果数据总是升序或降序,你可以做一个二进制升序或二进制降序搜索,然后你可以检查找到的结果中哪个是最接近的:

function closestIndex(value, arr, compare, from = 0, to = arr.length) {

  if (from >= to) return to;
  const mid = Math.floor((from + to) / 2);
  if (compare(arr[mid], value)) {
    return closestIndex(value, arr, compare, from, mid);
  }
  return closestIndex(value, arr, compare, mid + 1, to);
}

function searchClosest(value, arr) {
  const minIndex = closestIndex(value, arr, (a, b) => a <= b);
  const maxIndex = closestIndex(value, arr, (a, b) => a >= b);
 return Math.abs(arr[minIndex] - value) > Math.abs(arr[maxIndex] - value) ? maxIndex : minIndex;
}

请注意,这仍然是 O(log n)。

【讨论】:

  • 我还没有考虑过边缘情况,例如如果一个值大于数组中的最大值或小于最小值。在这种情况下,双向搜索不会产生结果,因此无论是对还是错,比较都会返回minIndex。我不会解决这个问题,这取决于你,亲爱的读者:)
  • 我不想要排序数据的原因是数据已经排序 - 可以是 asc(如 ID 0、1、4、15、18、...)或 desc(如时间戳中的时间格式>新时间比旧时间具有更高的值)-标准最接近的索引函数之间也存在差异(例如您的,我不想要)-如果值小于最小值,在这种情况下返回-1(如不存在index) - 试试这个编辑过的演示 jsfiddle.net/aubns9Lp (index is down by 1 to for understand)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 2014-06-12
相关资源
最近更新 更多