[英]javascript: how to find the key in an associative array that is closest to a value?
[英]Javascript find the closest number in an array of objects and retrieve the object's key value
我有一个对象数组(带有keys
: name
, quoteNumber
),我想找到小于给定数字的最接近的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.