Scala相当于R的Mapply?

时间:2016-07-02 01:49:50

标签: r scala foreach mapply

我来自R背景,所以我习惯使用R的* apply系列函数。

Scala的list.foreach(_.fun)list.map(_.fun)函数与R的lapply(list, fun)函数非常相似,因为它们都迭代地对列表的每个元素执行一个函数。

但是,R还有一个函数mapply(fun, list1, list2, ...),当一个函数有多个列表并希望在每个列表的第一个元素,每个元素的第二个元素上应用函数时,它很有用,依此类推。例如,如果我有一个函数add(x, y, z),两个列表x=(1, 2, 3)y=(2, 3, 4)z=(3, 4, 5)mapply(add, x, y, z)将返回(6, 9, 12)。< / p>

Scala与R mapply有任何等价物,而不使用for循环吗?

1 个答案:

答案 0 :(得分:2)

标准库中没有类似的例程,但您可以接近:

scala> List(List(1,2,3),List(5,6,7),List(14,13,12)).transpose
res3: List[List[Int]] = List(List(1, 5, 14), List(2, 6, 13), List(3, 7, 12))

scala> List(List(1,2,3),List(5,6,7),List(14,13,12)).transpose.map(_.sum)
res4: List[Int] = List(20, 21, 22)

注意:transpose要求所有子集合具有相同的大小。

跟进到您的评论。

我不确定你明白zipped是什么。它将元组(Tuple2)内的2个子集合转换为单个元组集合,然后可以将每个子集合赋予一个带有给定类型的2个参数的函数。这也适用于Tuple3内的3个子集合,成为三元组的集合,但这是限制。

另外,我不知道为什么你认为“zipped是一个函数调用而不是两个”。如果您按照他的评论中提到的link Richard Scriven,并比较提供的两个解决方案,您会看到他们有相同数量的步骤/陈述。

我认为,优点/缺点如下:

  • 如果您正在处理不同类型的集合,例如Seq[Int]Seq[Char],那么在将“组合器”功能应用于它们之前,您需要获取它们zippedf(i1,c1)然后f(i2,c2)然后f(i3,c3)等。
  • 这两种方法都不能很好地处理不同大小的子集合。 transpose将抛出异常,而zipped只会忽略最小子集合的max-index之外的所有元素。
  • 如果您的“合并器”功能需要三个以上的参数,那么您就无法使用zipped
  • 如果您的“合并器”将集合作为输入,那么transpose可能是更好/更容易的选择。