Javascript在对象数组中查找最接近的数字并检索对象';s键值 我有一个对象数组(用键:名称 >代码> QuotoNo.,我想找到比给定数字小的最近的 QuotoNo.,然后检索该对象的名称,我考虑使用for循环来移除更大的值,并从剩余的值中获得最大值,然而,考虑到数据集的规模,这可能不是最好的选择。这是其他更有效的算法吗?谢谢 const givenNum = 45 var array = [ { name: "Sally", quoteNumber: 35}, { name: "Jane", quoteNumber: 20}, { name: "Edwin", quoteNumber: 55}, { name: "Carrie", quoteNumber: 47}]; //'result:' Sally

Javascript在对象数组中查找最接近的数字并检索对象';s键值 我有一个对象数组(用键:名称 >代码> QuotoNo.,我想找到比给定数字小的最近的 QuotoNo.,然后检索该对象的名称,我考虑使用for循环来移除更大的值,并从剩余的值中获得最大值,然而,考虑到数据集的规模,这可能不是最好的选择。这是其他更有效的算法吗?谢谢 const givenNum = 45 var array = [ { name: "Sally", quoteNumber: 35}, { name: "Jane", quoteNumber: 20}, { name: "Edwin", quoteNumber: 55}, { name: "Carrie", quoteNumber: 47}]; //'result:' Sally,javascript,arrays,object,max,Javascript,Arrays,Object,Max,我制作了一个简单的一行程序,它用较大的引号将所有元素踢出,对其他元素进行排序,最后得到第一个元素(->最接近的元素): 如果它是未分类的,那么最有效的方法就是单次通过 函数getHighestQuote(引号,限制){ 设winner=null; 让winningQuote=null; for(让{name,quoteNumber}个引号){ 如果(quoteNumber>limit) 继续; if(winningQuote==null | | winningQuote{ const diff=

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


如果它是未分类的,那么最有效的方法就是单次通过

函数getHighestQuote(引号,限制){
设winner=null;
让winningQuote=null;
for(让{name,quoteNumber}个引号){
如果(quoteNumber>limit)
继续;
if(winningQuote==null | | winningQuote

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

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

const givenNum=45
变量数组=[
{姓名:“萨利”,
quoteNumber:35},
{姓名:“简”,
quoteNumber:20},
{姓名:“埃德温”,
quoteNumber:55},
{姓名:“嘉莉”,
quoteNumber:47}];
const result=array.reduce((acc,item)=>{
const diff=givenNum-item.quoteNumber;
如果(项目编号console.log(result.item)这是基于@Jeremy Roman和@Jamiec的答案。我认为这会快一点,除非我做了蠢事:

const数组=[
{姓名:“萨利”,
quoteNumber:35},
{姓名:“简”,
quoteNumber:20},
{名称:“维尔玛”,
quoteNumber:31},
{姓名:“埃德温”,
quoteNumber:55},
{名称:“涅瓦”,
quoteNumber:30},
{姓名:“嘉莉”,
quoteNumber:47},
{姓名:“阿诺德”,
quoteNumber:29},
];
函数最接近于(引号,极限){
设winner=null;
设winningQuote=0;
常数极限加上一=极限+1;
for(设i=0;iwinningQuote){
winningQuote=quoteNumber;
winner=引用[i]。名称;
}
}
返回赢家;
}
log(最接近于(数组,45)的;
log(与(数组,30)最接近的值);

log(最接近于(数组,10)的
Question有一个神奇的词“大数据集”,所以您希望避免使用类似排序的amnything
O(nlogn)
。顺便说一下,如果您认为性能很重要,那么使用具有代表性的数据集进行基准测试并不是一个坏主意。这里有一个简单的例子(我不知道您的数据实际上是什么样子):“只需要分配几个堆栈变量”可以通过使用
for(var{name,quoteNumber}…
而不是
let
进行优化,因为它将重用变量引用,而不是创建一个新的。
var
并不是完全死机;)我相信现代JS引擎将消除这种差异(我更担心的是,
需要生成代码来处理非数组deopts),但我还没有检查程序集。如果差异可能重要,请随时在您选择的浏览器中进行基准测试。:)我对这个答案投赞成票。虽然我喜欢我的简洁,但这是一种100%最快的方法,它使用了大量的数据,并且有点时髦的基准测试。使用
for(让i=0;i
等似乎要快一点,除非我做错了什么。这是
的完美用例。reduce()
。这将是我的首选解决方案,reduce语句可以缩短为:
constresult=array.reduce((pv,cv)=>cv.quoteNumber(pv?.quoteNumber??0)?cv:pv,null)
@andi2.2确实可以,但在我的浏览器上有点奇怪,它比我的()慢,而在逻辑上(至少对我来说)看起来应该是这样的quicker@Jamiec谢谢你对我(现已删除)的帖子发表评论。看看基准测试,如果我将
quoteNumber:Math.random()*100
设置为
quoteNumber:Math.random()*10000
我得到Foo_reduceFind2作为Foo_filterSort的最快响应,速度仅慢14.66%。如果您将其设置为Math.random()*100000(以匹配条目数),则Foo_reduceFind、Foo_reduceFind2和Foo_filterSort将成为最快的组合。@Firefox中的Jamiec。在Chrome Foo_reduceFind中,Foo_reduceFind2和Foo_filterSort都是并列的,但是Foo_forLoop要快得多。
const closest_smaller = array.filter(a => a.quoteNumber <= givenNum).sort((a,b) => b.quoteNumber-a.quoteNumber)[0]
const closest_smaller = array.filter(a => a.quoteNumber <= givenNum).sort((a,b) => b.quoteNumber-a.quoteNumber)[0] ?? 0
const closest_smaller = array.sort((a,b) => b.quoteNumber-a.quoteNumber).find(a => a.quoteNumber <= givenNum) ?? 0