应该避免x._1,x._2 ......语法吗?

maw*_*dne 27 scala

我刚刚开始使用Scala.我发现自己经常使用元组变量.例如,这里是我写的一些代码:

/* Count each letter of a string and return in a list sorted by character
 * countLetter("test") = List(('e',1),('s',1),('t',2))
*/
def countLetters(s: String): List[(Char, Int)] = {
  val charsListMap = s.toList.groupBy((c:Char) => c)
  charsListMap.map(x => (x._1, x._2.length)).toList.sortBy(_._1)
}
Run Code Online (Sandbox Code Playgroud)

这个元组sytax(x._1,x._2等)是否受到Scala开发人员的不满?

Tra*_*own 28

Scala开发人员不赞成使用元组访问器吗?

简答:不.

稍微长一点(按一个字符)回答:是的.

_n在我看来,太多可能是代码气味,在你的情况下,以下内容更清晰:

def countLetters(s: String): List[(Char, Int)] =
  s.groupBy(identity).mapValues(_.length).toList.sortBy(_._1)
Run Code Online (Sandbox Code Playgroud)

有很多这样的方法mapValues是专门为减少对嘈杂的元组访问器的需求而设计的,所以如果你发现自己写_1了很多东西,这可能意味着你错过了一些很好的库方法.但偶尔他们是写作的最干净的方式(例如,_1我的重写中的最后一个).

另外需要注意的是,过度使用元组访问器应该被视为将元组推广到案例类的推动.考虑以下:

val name = ("Travis", "Brown")

println("Hello, " + name._1)
Run Code Online (Sandbox Code Playgroud)

相反:

case class Name(first: String, last: String)

val name = Name("Travis", "Brown")

println("Hello, " + name.first)
Run Code Online (Sandbox Code Playgroud)

第二个版本中的额外案例类定义为单行代码购买了大量可读性.


sen*_*nia 19

那么有一个更好的解决方案x._N.使用元组的常用方法是模式匹配:

charsListMap.map{case (a, b) => (a, b.length)}
Run Code Online (Sandbox Code Playgroud)

你也可以看看scalaz,有一些元组的工具:

import scalaz._
import Scalaz._

scala> (1, "a") bimap (_ + 2, _ + 2)
res0: (Int, java.lang.String) = (3,a2)

scala> ('s, "abc") :-> { _.length }
res1: (Symbol, Int) = ('s,3)
Run Code Online (Sandbox Code Playgroud)

  • @TravisBrown:你的答案中有`mapValues`,这是Map的方法.但模式匹配是更通用的解决方案.它几乎适用于元组的所有情况. (7认同)