我通过本书的练习来学习Scala" Scala for the Impatient"。一个练习要求:
编写一个循环,用于交换整数数组的相邻元素。对于 例如,数组(1,2,3,4,5)变为数组(2,1,4,3,5)
我用3种不同的方式做到了,其中一种方式如下。我很好奇这是否可以根据我内联的评论进行改进。
def swapWithGrouped(a: Array[Int]) = {
a.grouped(2).map {
// TODO: Can we use reverse here?
case Array(x, y) => Array(y, x)
// TODO: Can we use identity function here?
case Array(x) => Array(x)
}.flatten.toArray
}
答案 0 :(得分:5)
您可以使用.flatMap
代替.map{..}.flatten
你也不需要匹配单个元素数组,所以你可以简单地使用一个变量(虽然我觉得这真的取决于问题,有时候显示模式中的对称性很好并且使意图更加明确)。
所以:
scala> def swapWithGrouped(a: Array[Int]) = {
a.grouped(2).flatMap {
case Array(x, y) => Array(y, x)
case single => single
}.toArray
}
swapWithGrouped: (a: Array[Int])Array[Int]
scala> swapWithGrouped(a) // a is Array(1,2,3,4,5)
res0: Array[Int] = Array(2, 1, 4, 3, 5)
Array(x,y) => Array(y,x)
也很容易被读错,.reverse
使意图更明确,并且还有一个额外的好处就是可以删除单元素的情况。
scala> def swapWithGrouped(a: Array[Int]) = a.grouped(2).flatMap(_.reverse).toArray
swapWithGrouped: (a: Array[Int])Array[Int]
答案 1 :(得分:2)
不,AFAIK没有办法将模式绑定到名称。最接近这一点的是@运算符,但它不会对整个模式起作用 - 仅限于参数。
另一方面:
def swapWithGrouped(a: Array[Int]) = {
a.grouped(2).map{ _.reverse }.flatten.toArray
}
应该没问题。我假设你不关心表现;如果你这样做,代码将需要非常不同。