【问题标题】:Scala: What does zipped produce and why can it be mapped as a pair?Scala:zipped 会产生什么,为什么它可以成对映射?
【发布时间】:2014-02-13 05:29:35
【问题描述】:

在关于zipWithearlier question 中,@Martin Odersky 建议不要像

 foo zipWith(_ + _) bar

(其中 foobarSeq's)以下更好(并且实际上在 Scala 中有效)。

(foo, bar).zipped map (_ + _)

我的问题是map 怎么知道它的论点(从表面上看似乎是一对)应该分成两个元素?

以下内容实际上在工作表中运行。

val list1 = List(1, 2, 3, 4)                    //> list1  : List[Int] = List(1, 2, 3, 4)
val list2 = List(5, 6, 7, 8)                    //> list2  : List[Int] = List(5, 6, 7, 8)
val zippedResult = (list1, list2).zipped        //> list3  : scala.runtime.Tuple2Zipped[Int,List[Int],Int,List[Int]] = scala.run
                                              //| time.Tuple2Zipped@f4bf78da
zippedResult.mkString(", ")                     //> res4: String = (1,5), (2,6), (3,7), (4,8)
zippedResult map (_ + _)                        //> res5: List[Int] = List(6, 8, 10, 12)

我看到zippedResult 实际上有 4 个类型参数,而不仅仅是一对列表。

val list3 = List((1, 5), (2, 6), (3, 7), (4, 8))
                                              //> list3a  : List[(Int, Int)] = List((1,5), (2,6), (3,7), (4,8))
list3 == zippedResult                           //> res6: Boolean = false

我不会写

list3 map(_ +_ )

那么什么是Tuple2Zipped 类型,它可以为map 函数提供两个参数? zipped 是创建它实例的唯一方法吗?

【问题讨论】:

  • 虽然您不能为.zipped 序列编写map(_ + _),但您仍然可以使用大小写匹配来获取各个元素:list3 map { case (a,b) => a+b }。不是那么短,但它是一些东西。

标签: scala


【解决方案1】:

它是runtime.Tuple2Zipped。您可以像这样手动创建一个实例:

val zipped = new Tuple2Zipped(Seq(1, 2), Seq(3, 4))

这里是source of map method

方法map 声明如下(简化):

def map[B](f: (El1, El2) => B): Seq[B]

Tuple2Zipped 不是任何 scala 集合类型的后代,因此其 map 方法与常规 scala 集合的 map 方法无关。

【讨论】:

  • 感谢您的回答。这是有道理的,这将是一个特例,它的map 将不同于所有其他map。我很惊讶这没有得到更多的宣传。
  • 这真是一个发现,从没想过有一些像收藏一样但又与众不同的东西。还有Tuple3Zipped,它允许更多有趣的构造(a, b, c).zipped map (_ * _ + _)。可惜3之后就没有续集了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多