在clojure中我们有一个map函数,你可以在其中提供一个函数和两个集合
(map + [1 2 ] [4 5 ]) ;;=> (5 7 )
Scala中有类似内容吗?
我试着理解,但后来我得了4个组合。
如果有一种方法可以理解,会更好,因为我将来必须做一些过滤/
答案 0 :(得分:5)
您可以先使用.zip
将两个集合合并为一个,然后映射:
seq1.zip(seq2).map { case (x, y) => x + y }
我不认为这是理解的可能性。您也可以通过拨打.filter
或.filterNot
进行过滤。
答案 1 :(得分:1)
@JoeK为您提供了具体的答案。
我将为您提供两个更一般的答案。 Clojure和许多其他动态语言经常会在arity上进行抽象(标准库的map
和apply
函数就是很好的例子)。在没有依赖类型的情况下,这在静态类型语言中很难做到。您将看到的一般模式是根据需要多次重复应用函数。在这种情况下,如果你需要做
(map + [1 2 3] [4 5 6] [7 8 9])
你需要做
xs.zip(ys).zip(zs).map{ case (x, (y, z)) => x + y + z }
通常这个额外的样板并不可怕。当你想要抽象任意元组或任意案例类时,对于arity的抽象变得更加严重错过的地方。当Shapeless,一个Scala库为您提供有限形式的依赖类型时,就会发挥作用。
我不会因为这样的事情而打破Shapeless。
第二个一般观点是,你不能以你理解的方式输入列表(一般情况下不是这样...因为你可以比较Scala中的所有内容,你有点可以用一个最终的过滤器通过,但对于内置相等并不能满足你想要的任何东西都会失败。这背后的一般原则是更微妙的。事实证明,这些集合函数的权力等级。你从map
开始。如果您添加zip
和List.apply
,则会跳转到下一个级别。如果您将zip
替换为flatten
,则会获得另一个级别。使用flatten
,您可以恢复zip
的版本,但不能相反。
对于集合,默认Scala flatMap
和flatten
(请注意,对于理解最终是一系列flatMap
调用)确实会产生zip
形式,即具有相同类型签名的东西,但事实证明它是笛卡尔产品。
有flatten
的版本确实会产生标准zip
,但只有当所有的集合长度相同时才有意义。它涉及从集合集合中获取方形矩阵的对角线。
这对于有限集合通常不那么有用,因为Scala的类型系统不足以表达恒定长度约束,如果你不确保长度一致,你会得到一些奇怪的行为。
另一方面,这是flatten
和flatMap
的版本,它实际上对无限流有用(其中等价的List.apply
是无限常量流)而#&# 34;正常"版本flatten
无法通过处理第一个流。
旁注:您当然可以在以后总是使用您的压缩列表进行理解(您可以在其中进行一些过滤)。你无法在理解中实现拉链本身。
答案 2 :(得分:0)
这里并没有真正添加任何新内容,但也许这会有所帮助:
def mapCollections[A,B,C](as: Seq[A], bs: Seq[B])(f: (A,B) => C): Seq[C] =
as zip bs map f.tupled
mapCollections(List(1, 2), List(4, 5))(_ + _) // = List(5, 7)