在元组列表上使用map()时的详细表示法

fle*_*end 19 scala list

我喜欢让我的代码非常天真可读.

如果我设置一个简单的元组列表:

scala> val a = List(6, 8, 10)
a: List[Int] = List(6, 8, 10)

scala> val b = a zipWithIndex
b: List[(Int, Int)] = List((6,0), (8,1), (10,2))
Run Code Online (Sandbox Code Playgroud)

我想在List上映射(),但我发现._1 ._2语法有点难以阅读:

scala> val c = b map ( a => if(a._1 > 8) a._1 else a._2 )           
c: List[Int] = List(0, 1, 10)
Run Code Online (Sandbox Code Playgroud)

为了"命名"元组,我用过:

scala> val c = b map ( { case (num, i) => if(num > 8) num else i } )
c: List[Int] = List(0, 1, 10)
Run Code Online (Sandbox Code Playgroud)

两个问题:

1)有没有更简洁的方法来命名元组成员?

2)上面的版本是否有相当大的性能损失(它用于中等性能关键代码).

谢谢.

Lui*_*hys 20

b map Function.tupled((num, i) => if(num > 8) num else i)
Run Code Online (Sandbox Code Playgroud)

避免模​​式匹配和for表达式因此应该合理地执行.我通常只是case像你一样使用它.

  • 如果你想缩短它,可以导入`Function.tupled`.或者,如果您想赢得混淆的Scala比赛,请将其作为符号导入!`import Function.{tupled =>*}`现在你可以写`b map*((num,i)=> if(num> 8)num else i)` (2认同)

Pao*_*lla 8

在这种情况下,您可能会发现等效的for-comprehension语法更具可读性,但它确实是一个品味问题......

for {(num, i) <- b} yield if(num >8) num else i
Run Code Online (Sandbox Code Playgroud)

FWIW,我已尝试使用和不使用模式匹配对地图进行基准测试,并且我的执行时间几乎相同.

我用过的代码:

object bench extends scala.testing.Benchmark {
    var b:List[(Int, Int)] = _

    override def setUp {
        val a = (1000000 to 2000000).toList
        b = a zipWithIndex
    }

    def run = b map ( a => if(a._1 > 8) a._1 else a._2 )
 }
Run Code Online (Sandbox Code Playgroud)

我还创建了另一个带有bench1对象的应用程序,该对象只有带有模式匹配的map版本而不是._1._2.我的旧上网本上的结果(scala 2.9.1,xubuntu 11.10):

$ scala bench 10 
bench$   750    758 731 721 733 736 725 743 735 736
$ scala bench1 10
bench1$  774    772 740 724 745 730 711 739 740 740
Run Code Online (Sandbox Code Playgroud)