【问题标题】:Scala reduction with non-primitive lists使用非原始列表进行 Scala 缩减
【发布时间】:2018-11-01 00:48:27
【问题描述】:

以下函数计算 Scala 中两个 2D 点之间的欧几里得距离:

def euclideanDist(pt1: List[Double], pt2: List[Double]): Double =
  sqrt(pow(pt1(0)-pt2(0), 2)+pow(pt1(1)-pt2(1), 2))

我想设计一个周界函数来累积点列表(或 ListBuffer)中每个连续点之间的距离。

例如

val arr:ListBuffer[List[Double]] = ListBuffer(List(0, 0), List(0,1), List(1,1), List(1,0), List(0, 0))
perimeter(arr)

应该给出输出为 4。

这是我尝试过的:

def perimeter(arr: ListBuffer[List[Double]]): Double = 
  arr.reduceLeft(euclideanDist)

在执行时,编译器会抛出此错误

Name: Unknown Error
Message: <console>:43: error: type mismatch;
 found   : (List[Double], List[Double]) => Double
 required: (Any, List[Double]) => Any
         arr.reduceLeft(euclideanDist)
                        ^
<console>:43: error: type mismatch;
 found   : Any
 required: Double
         arr.reduceLeft(euclideanDist)
                       ^
StackTrace:

我可以使用 for 循环来完成整个事情,但想知道这是否可以通过 Scala 方式更简单地解决。

【问题讨论】:

  • 不是def perimeter(ListBuffer[List[Double]]: arr) 应该是def perimeter(arr: ListBuffer[List[Double]])
  • @RameshMaharjan:是的。在 SO 中重构时犯了一个错误。刚刚做了编辑。 (虽然错误仍然相同:))

标签: scala list function


【解决方案1】:

这是怎么回事:

val arr:List[List[Double]] = List(List(0, 0), List(0,1), List(1,1), List(1,0), List(0, 0))

arr.sliding(2).map{case List(a,b) => euclideanDist(a,b)}.sum

【讨论】:

  • 来自scala-lang.org/files/archive/api/current/scala/collection/…def sliding(size: Int): Iterator[Seq[A]] Groups elements in fixed size blocks by passing a "sliding window" over them (as opposed to partitioning them, as is done in grouped.) The "sliding window" step is set to one.
  • arr.sliding(2).toList res1: List[List[List[Int]]] = List(List(List(0, 0), List(0, 1)), List(List(0, 1), List(1, 1)), List(List(1, 1), List(1, 0)), List(List(1, 0), List(0, 0))) 滑动将元素作为 2 个元素列表返回。所以你可以通过模式匹配来解包case List(a,b)map( l match { case List(a,b) =&gt; }的合成糖
猜你喜欢
  • 1970-01-01
  • 2017-05-04
  • 2011-02-05
  • 2019-12-18
  • 2019-07-05
  • 1970-01-01
  • 2012-09-22
  • 2021-01-15
  • 1970-01-01
相关资源
最近更新 更多