找到键值接近给定值的对象的有效方法

时间:2017-05-01 22:31:23

标签: javascript ecmascript-6

我正在使用ES6。假设我有一个如下所示的排序数组。不使用lodash或除jquery之外的任何其他库。

    sortedArray = [
    {a: "a", b: 2, c: "something1"},
    {a: "a1", b: 3, c: "something2"},
    {a: "a2", b: 4, c: "something3"},
    {a: "a3", b: 5, c: "something4"},
    {a: "a4", b: 6, c: "something5"},
    {a: "a5", b: 7, c: "something6"}
]

是否有一种有效的方法来找出其键值b值最接近所提供值的对象。

如果我提供值3.9,则应返回{a: "a2", b: 4, c: "something3"}

感谢任何帮助。

3 个答案:

答案 0 :(得分:6)

使用reduce(因此在大数组上应该很慢......):

sortedArray = [
    {a: "a", b: 2, c: "something1"},
    {a: "a1", b: 3, c: "something2"},
    {a: "a2", b: 4, c: "something3"},
    {a: "a3", b: 5, c: "something4"},
    {a: "a4", b: 6, c: "something5"},
    {a: "a5", b: 7, c: "something6"}
]
const search = 3.9
sortedArray.reduce((p,v)=> Math.abs(p.b-search) < Math.abs(v.b-search) ? p : v)
// {a: "a2", b: 4, c: "something3"}

答案 1 :(得分:3)

不是计算效率最高,但我能想到的最短:

STUFF

答案 2 :(得分:1)

由于您明确要求在排序对象数组中找到最接近元素的有效方法,我建议采用二进制搜索策略:

0array.length - 1的整个索引间隔开始,然后查看中间元素:

  • 它更小吗?继续在较高的时间间隔内搜索。
  • 它更大吗?继续在较低的时间间隔内搜索。

此搜索策略在对数步数中找到最接近的元素,即在O(log n)中。通过reduce搜索在O(n)中完成并按差异排序并选择顶部元素在O(n log n)中完成。

结果代码肯定不优雅,但效率很高:

&#13;
&#13;
// Find object whose b is closest to value:
function findClosest(objects, value) {
  let lowest = 0;
  let highest = objects.length - 1;
  let difference = Infinity;
  let closest;
  
  while (lowest <= highest) {
    let index = highest + lowest >> 1;
    let current = objects[index];
    
    if (Math.abs(current.b - value) < difference) {
      closest = current;
      difference = Math.abs(closest.b - value);
    }
    if (current.b > value) {
      highest = index - 1;
    } else if (current.b < value) {
      lowest = index + 1;
    } else {
      break;
    }
  }
  return closest;
}

// Example:
let sortedArray = [
  {a: "a" , b: 2, c: "something1"},
  {a: "a1", b: 3, c: "something2"},
  {a: "a2", b: 4, c: "something3"},
  {a: "a3", b: 5, c: "something4"},
  {a: "a4", b: 6, c: "something5"},
  {a: "a5", b: 7, c: "something6"}
];

console.log(findClosest(sortedArray, 3.9));
&#13;
&#13;
&#13;