如何优雅地找到元素?

时间:2017-03-23 02:32:58

标签: javascript

给定以下数组命名的簇,获得距离最小值的对象的优雅方法是什么?对不起,这里有一个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的单线程?或者同样简单的东西

3 个答案:

答案 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')); 或添加其他条件。谢谢你的提问!