我们可以改进我的代码来交换Scala中的相邻数组元素吗?

时间:2015-04-29 05:16:44

标签: arrays scala swap

我通过本书的练习来学习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
}

2 个答案:

答案 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
  }

应该没问题。我假设你不关心表现;如果你这样做,代码将需要非常不同。