有没有办法在不使用临时变量和启动新语句的情况下操作元组的多个值?
假设我有一个方法返回一个元组,我想用内联这些值做一些事情.
例如,如果我想在某个点拆分一个字符串并反转这些部分
def backToFront(s: String, n:Int) = s.splitAt(n)...
Run Code Online (Sandbox Code Playgroud)
我可以
val (a, b) = s.splitAt(n)
b + a
Run Code Online (Sandbox Code Playgroud)
(需要临时变量和新声明)或
List(s.splitAt(n)).map(i => i._2 + i._1).head
Run Code Online (Sandbox Code Playgroud)
(工作,但似乎有点脏,为此创建一个单独的元素列表)或
s.splitAt(n).swap.productIterator.mkString
Run Code Online (Sandbox Code Playgroud)
(适用于这个特定的例子,但只是因为碰巧有一种swap方法可以做我想要的,所以它不是很一般).
zipped关于元组的方法似乎只适用于列表元组.
另一个例子,你怎么能把元组('a, 'b, 'c)变成('b, 'a, 'c)一个声明?
元组只是方便的返回类型,并不假设您将使用它进行复杂的操作.还有关于scala论坛的类似讨论.
关于最后一个例子,找不到比模式匹配更好的东西.
('a, 'b, 'c) match { case (a, b, c) => (b, a ,c) }
Run Code Online (Sandbox Code Playgroud)
不幸的是,元组的内置方法非常有限.
也许你想在你的个人图书馆里找到这样的东西,
def fold2[A, B, C](x: (A, B))(f: (A, B) => C): C = f(x._1, x._2)
def fold3[A, B, C, D](x: (A, B, C))(f: (A, B, C) => D): D = f(x._1, x._2, x._3)
Run Code Online (Sandbox Code Playgroud)
通过适当的隐式转换,您可以这样做,
scala> "hello world".splitAt(5).swap.fold(_ + _)
res1: java.lang.String = " worldhello"
scala> (1, 2, 3).fold((a, b, c) => (b, c, a))
res2: (Int, Int, Int) = (2,3,1)
Run Code Online (Sandbox Code Playgroud)
最后一个表达式的替代方法是"管道"运算符|>(从Scalaz或此处获取),
scala> ('a, 'b, 'c) |> (t => (t._2, t._3, t._1))
res3: (Symbol, Symbol, Symbol) = ('b,'c,'a)
Run Code Online (Sandbox Code Playgroud)
如果没有所需的注释,这将是很好的,
scala> ("hello ", "world") |> (((_: String) + (_: String)).tupled)
res4: java.lang.String = hello world
Run Code Online (Sandbox Code Playgroud)