如何在Scala for推导式内直接求两个GPS坐标列表的最短距离?
直接在遍历过程中求最小GPS距离的方法
当然可以!你完全不需要生成完整的距离列表再找最小值——这样不仅能节省内存(尤其是当坐标列表规模很大时),代码也能更高效。结合Scala的集合特性,有几种简洁的方式实现这个需求:
方法1:用foldLeft累积最小值
这种方式最直接,全程只追踪当前的最小距离,不会生成任何中间列表:
// 初始值设为Double的最大值,确保第一个计算出的距离会替换它 val minDistance = coordinatesList1.foldLeft(Double.MaxValue) { (currentMin, c1) => coordinatesList2.foldLeft(currentMin) { (acc, c2) => val distance = calculateDistances(c1, c2) math.min(acc, distance) } }
外层foldLeft遍历第一个列表的每个坐标c1,内层foldLeft遍历第二个列表的每个坐标c2,每次计算距离后和当前累积的最小值比较,只保留更小的那个值。
方法2:用懒加载视图+for推导式求min
如果你想保留类似原代码的for推导式风格,可以给列表加上view(懒加载视图),这样不会提前生成所有距离的列表,而是计算一个、比较一个,直到找到最小值:
val minDistance = (for { c1 <- coordinatesList1.view c2 <- coordinatesList2.view } yield calculateDistances(c1, c2)).min
如果担心列表为空导致min抛出异常,可以改用minOption获取一个Option[Double]:
val minDistanceOption = (for { c1 <- coordinatesList1.view c2 <- coordinatesList2.view } yield calculateDistances(c1, c2)).minOption // 后续可以用模式匹配处理: minDistanceOption match { case Some(min) => println(s"最小距离是:$min") case None => println("其中一个坐标列表为空,无法计算距离") }
两种方法对比
foldLeft的方式性能略优,因为它不需要构建任何中间迭代器;- 视图+for推导式的写法更贴近你原来的代码结构,可读性更强,适合追求代码简洁的场景。
内容的提问来源于stack exchange,提问作者Jish Nair
相关产品推荐
相关产品推荐

