繁体   English   中英

Javascript 在对象数组中找到最接近的数字并检索对象的键值

[英]Javascript find the closest number in an array of objects and retrieve the object's key value

我有一个对象数组(带有keysnamequoteNumber ),我想找到小于给定数字的最接近的quoteNumber然后检索该对象的名称,我考虑使用 for 循环来删除较大的值,并且从剩余的值中获取最大值,但考虑到数据集的大小,它可能不是最佳选择。 这是任何其他更有效的算法吗? 谢谢!

const givenNum = 45
var array = [ 

    { name: "Sally",
      quoteNumber: 35},
    { name: "Jane",
      quoteNumber: 20},
    { name: "Edwin",
      quoteNumber: 55},
    { name: "Carrie",
      quoteNumber: 47}];

//'result:' Sally

如果它没有排序,那么你可以做到的最有效的方法就是单次通过。

function getHighestQuote(quotes, limit) {
  let winner = null;
  let winningQuote = null;
  for (let {name, quoteNumber} of quotes) {
    if (quoteNumber > limit)
      continue;
    if (winningQuote === null || winningQuote < quoteNumber) {
      winner = name;
      winningQuote = quoteNumber;
    }
  }
  return winner;
}

它不像函数式方法那么时髦,但它是一个线性时间传递,只需要分配几个堆栈变量。

如果你有一个大数据集,你要避免做任何事情,要么在数组上循环多次,甚至在查找之前尝试对其进行排序。 一个简单的聚合操作就可以做到这一点。 使用reduce

 const givenNum = 45 var array = [ { name: "Sally", quoteNumber: 35}, { name: "Jane", quoteNumber: 20}, { name: "Edwin", quoteNumber: 55}, { name: "Carrie", quoteNumber: 47}]; const result = array.reduce ( (acc,item) => { const diff = givenNum - item.quoteNumber; if(item.quoteNumber < givenNum && diff < acc.diff) acc = {diff, item} return acc; },{ diff: Number.MAX_SAFE_INTEGER, item: null }); console.log(result.item);

另请注意,如果速度真的很重要,也请避免使用此解决方案 - 它有额外的方法调用,您不会使用更简单的循环解决方案 这将永远是最快的选择。

我做了一个简单的单行,它踢出所有具有较大引号编号的元素,对其他元素进行排序,最后得到第一个元素(-> 最接近的元素):

const closest_smaller = array.filter(a => a.quoteNumber <= givenNum).sort((a,b) => b.quoteNumber-a.quoteNumber)[0]

如果 givenNum 小于每个 quoteNumber,则返回 undefined。 如果你想有一个后备使用:

const closest_smaller = array.filter(a => a.quoteNumber <= givenNum).sort((a,b) => b.quoteNumber-a.quoteNumber)[0] ?? 0

您也可以使用find而不是filter ,我不知道哪个更快:

const closest_smaller = array.sort((a,b) => b.quoteNumber-a.quoteNumber).find(a => a.quoteNumber <= givenNum) ?? 0

这是基于@Jeremy Roman 和@Jamiec 的回答。 我认为这会快一点,除非我做了一些愚蠢的事情: https://jsbench.me/g0kmha8buo/1

 const array = [ { name: "Sally", quoteNumber: 35}, { name: "Jane", quoteNumber: 20}, { name: "Velma", quoteNumber: 31}, { name: "Edwin", quoteNumber: 55}, { name: "Neva", quoteNumber: 30}, { name: "Carrie", quoteNumber: 47}, { name: "Arnold", quoteNumber: 29}, ]; function closest_quote_less_than_or_equal_to(quotes, limit) { let winner = null; let winningQuote = 0; const limit_plus_one = limit + 1; for(let i = 0; i < quotes.length; i++) { const quoteNumber = quotes[i].quoteNumber; if(((quoteNumber < limit_plus_one) * quoteNumber) > winningQuote) { winningQuote = quoteNumber; winner = quotes[i].name; } } return winner; } console.log(closest_quote_less_than_or_equal_to(array, 45)); console.log(closest_quote_less_than_or_equal_to(array, 30)); console.log(closest_quote_less_than_or_equal_to(array, 10));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM