Scala:列表到列表列表,惯用吗?
Scala: List to List of Lists, idiomatically?
在 Scala 中,我写了一个高阶函数来迭代一个列表,并为每个元素用头和列表回调,即:
def headAndSelf[A, B](li: List[A], f: (A, List[A]) => B): List[B] = {
if (li == Nil) Nil
else f(li.head, li) :: headAndSelf(li.tail, f)
}
给定 val a = List(1,2,3)
scala> headAndSelf(a, (x: Int, y: List[Int]) => (x,y))
res4: List[(Int, List[Int])] = List((1,List(1, 2, 3)), (2,List(2, 3)), (3,List(3)))
然后我想到我可以从列表中得到头部,所以写起来更简单:
def self[A, B](li: List[A], f: (List[A]) => B): List[B] = {
if (li == Nil) Nil
else f(li) :: self(li.tail, f)
}
(尽管它让 lambda 变得不那么优雅了)
scala> self(a, (x: List[Int]) => x)
res7: List[List[Int]] = List(List(1, 2, 3), List(2, 3), List(3))
然后我想,肯定有一种更简单、惯用的方法可以将列表转换为列表的列表。那是什么?
额外问题:为什么 Scala 不能推断 lambda 的类型? a
是 List[Int]
,所以 x
也应该是 List[Int]
,不是吗?:
scala> self(a, x => x)
<console>:13: error: missing parameter type
self(a, x => x)
^
tails
将完成大部分工作。
tails
将有一个空列表作为其最后一个元素,您需要将其过滤掉,这就是 collect
下面所做的:
def headAndSelf[A,B](l: List[A])(f: (A, List[A]) => B) =
l.tails.collect{case list @ head :: _ => f(head, list)}.toList
具有此处演示的两个参数列表将允许正确的类型推断。您在呼叫站点也需要两个列表,但通常很方便:
headAndSelf(yourList){(h,l) => whatever}
在 Scala 中,我写了一个高阶函数来迭代一个列表,并为每个元素用头和列表回调,即:
def headAndSelf[A, B](li: List[A], f: (A, List[A]) => B): List[B] = {
if (li == Nil) Nil
else f(li.head, li) :: headAndSelf(li.tail, f)
}
给定 val a = List(1,2,3)
scala> headAndSelf(a, (x: Int, y: List[Int]) => (x,y))
res4: List[(Int, List[Int])] = List((1,List(1, 2, 3)), (2,List(2, 3)), (3,List(3)))
然后我想到我可以从列表中得到头部,所以写起来更简单:
def self[A, B](li: List[A], f: (List[A]) => B): List[B] = {
if (li == Nil) Nil
else f(li) :: self(li.tail, f)
}
(尽管它让 lambda 变得不那么优雅了)
scala> self(a, (x: List[Int]) => x)
res7: List[List[Int]] = List(List(1, 2, 3), List(2, 3), List(3))
然后我想,肯定有一种更简单、惯用的方法可以将列表转换为列表的列表。那是什么?
额外问题:为什么 Scala 不能推断 lambda 的类型? a
是 List[Int]
,所以 x
也应该是 List[Int]
,不是吗?:
scala> self(a, x => x)
<console>:13: error: missing parameter type
self(a, x => x)
^
tails
将完成大部分工作。
tails
将有一个空列表作为其最后一个元素,您需要将其过滤掉,这就是 collect
下面所做的:
def headAndSelf[A,B](l: List[A])(f: (A, List[A]) => B) =
l.tails.collect{case list @ head :: _ => f(head, list)}.toList
具有此处演示的两个参数列表将允许正确的类型推断。您在呼叫站点也需要两个列表,但通常很方便:
headAndSelf(yourList){(h,l) => whatever}