【问题标题】:scala map function of map vs. list地图与列表的scala地图功能
【发布时间】:2016-10-19 15:51:53
【问题描述】:

片段 1:

val l = List(1,2,43,4)
l.map(i => i *2)

片段 2:

val s = "dsadadaqer12"
val g = s.groupBy(c=>c)
g.map  ( {case (c,s) => (c,s.length)})

在 sn-p #2 中,语法与 #1 不同,即需要大括号——为什么? 我认为以下内容会编译,但事实并非如此:

g.map ( (c,s) => (c,s.length))

谁能解释一下原因?

谢谢

【问题讨论】:

    标签: scala


    【解决方案1】:

    两者的区别在于——后者使用Pattern Matching而前者不使用。

    g.map({case (c,s) => (c,s.length)}) 的语法只是语法糖:

    g.map(v => v match { case (c,s) => (c,s.length) })
    

    这意味着:我们将匿名函数的输入参数命名为v,然后在函数body中将其匹配到一个元组(c,s)。由于这非常有用,Scala 提供了您使用的速记版本。

    当然 - 这与您使用 Map 还是 List 没有任何关系 - 请考虑以下所有可能性:

    scala> val l = List(1,2,43,4)
    l: List[Int] = List(1, 2, 43, 4)
    
    scala> l.map({ case i => i*2 })
    res0: List[Int] = List(2, 4, 86, 8)
    
    scala> val l2 = List((1,2), (3,4))
    l2: List[(Int, Int)] = List((1,2), (3,4))
    
    scala> l2.map({ case (i, j) => i*j })
    res1: List[Int] = List(2, 12)
    
    scala> val g = Map(1 -> 2, 3 -> 4)
    g: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
    
    scala> g.map(t => t._1 * t._2)
    res2: scala.collection.immutable.Iterable[Int] = List(2, 12)
    

    Map 和 List 都可以使用这两种语法选项,这主要取决于您实际想要做什么。

    【讨论】:

    • 更多语法糖也是可能的:g.map{case (c, s) => (c, s.length)}
    【解决方案2】:

    1-g.map{case (c,s) => (c,s.length)}

    2-g.map((c,s) => (c,s.length))

    map 方法从 g 集合中提取一个参数,一个 2 元组。第一个示例可以编译,因为case 语句使用模式匹配来提取元组的元素,而第二个示例没有并且不会编译。为此,您必须执行以下操作:g.map(t => (t._1, t._2.length))

    至于括号与花括号:“部分函数”始终需要大括号,这就是case 语句的含义。您可以对匿名函数(即x => ...)使用大括号或括号,但如果函数不止一行(即有回车符),则需要使用大括号。

    我在某处读到,这种括号/大括号的区别可能会放宽,但我不知道这是否会很快发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 2017-07-30
      • 2011-04-30
      • 2020-07-06
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多