给定以下数组命名的簇,获得距离最小值的对象的优雅方法是什么?对不起,这里有一个JS新手。
var clusters = []
clusters.push({
description:"Frankfurt",
distance:18492.53622406789,
id:"ahcg4_rnrCJ2kQJ-BkP3v4JS",
url:"https://frankfurt.example.com",
name:"eu-central-1"
})
clusters.push({
description:"Oregon",
distance:11471.556955008904,
id:"6RazgBDmGW0GBAyokoLFNyYp",
manager_url:"https://oregon.example.com",
name:"us-west-2"
})
通过使用reduce或类似方法,必须有比传统for循环更优雅的方法吗?例如我怎么把它写成带有reduce的单线程?或者同样简单的东西
答案 0 :(得分:2)
要找到最小值,您将根据定义访问每个元素。访问每个元素涉及某种迭代,无论是for循环,还是reduce
,如:
clusters.reduce(
(smallest, cluster) => cluster.distance < smallest.distance ? cluster : smallest);
您还可以考虑按距离对数组进行排序并获取结果的第一个(最小)元素:
clusters.slice().sort((x, y) => x.distance - y.distance)[0]
然而,这比你真正需要做的更多。
另一种选择,如果你有数十万个这样的对象,那就是缓存具有最小值的元素,并在元素添加到数组时更新它。
let clusterWithSmallestDistance;
function addCluster(cluster) {
if (!clusterWithSmallestDistance ||
cluster.distance < clusterWithSmallestDistance.distance)
clusterWithSmallestDistance = cluster;
clusters.push(cluster);
}
答案 1 :(得分:1)
将评论转移到答案,因为你说它有帮助。使用Array.prototype.reduce,您可以遍历数组,比较当前和下一个项目,并返回距离较小的任何一个,最后返回整个数组中距离最小的对象。
var smallest = clusters.reduce(
function(current, next) {
return current.distance < next.distance ? current : next;
}
);
你也可以对ES6更简洁一点。
let smallest = clusters.reduce((current, next) =>
current.distance < next.distance ? current : next;
);
答案 2 :(得分:0)
我也想提供我的意见。我被这种问题所吸引..
APPaymentList
或者
let _min = (a,b) => Math.min(a,b);
//Making it our own function the because `reduce` callback has other parameters
//Also - aesthetics
let smallestDistance = cluster.map(c => c.distance)
.reduce(_min);
但我认为你可能想保留对距离最小的物体的参考,在这种情况下,torazaburo已经给出了答案,这是我自己对解决方案的触摸
let distances = cluster.map(c => c.distance);
let smallestDistance = Math.min(...distances);
上述代码未涵盖的一种情况是2个对象具有相同的距离。代码假设您将后一个值放在数组中。要反转,您可以使用let _getSmaller = prop => (a,b) => a[prop] < b[prop] ? a : b;
let nearest = cluster.reduce(_getSmaller('distance'));
或添加其他条件。谢谢你的提问!