Scala:减去奇数的索引

Scala: subtract index of odd values

对于实际练习,我需要定义一个函数,该函数基本上更改列表中奇数索引中每个值的索引,这样我会得到这个:

changePairs(List(1,2,3,4,5,6,7,8,9,10,11)) 
//> res62: List[Int] = List(2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 11)

changePairs(List(2,2,30,4,50,6,7,80,9,100)) 
//> res63: List[Int] = List(2, 2, 4, 30, 6, 50, 80, 7, 100, 9)

所以基本上我需要交换每个奇偶对的位置,以防万一我在最后一个索引处留下一个奇数元素(第一个示例中的 11),我将其保持原样.

我有这个,但肯定没用,我也不确定为什么。

def changePairs(a: List[Int]) = a.zipWithIndex.map {
 case (s,i) => if (i % 2 != 0) a.patch(i,Seq(s),1); a.patch(i-2,Seq(s),0);
} 

这是一种方法:

def changePairs(a: List[Int]) = a.grouped(2).flatMap {
  case List(a, b) => List(b, a)
  case a => a
}.toList

changePairs(List(1, 2, 3, 4, 5, 6, 7)) // List(2, 1, 4, 3, 6, 5, 7)

让你继续前进的主要想法是一旦你想到将列表分组为两个元素的子列表,这就是 grouped(2) 所做的。从那时起,它就很容易了——描述两种情况,一种有两个元素(在那种情况下我们翻转它们),另一种只有一个元素,比如我的例子中的 7,在这种情况下我们就让它保持原样。我们使用 flatMap 将 2 元素列表的结果列表展平为一个大列表,并且我们使用 .toList 来退出我们从 grouped.[=17= 获得的迭代器]

编辑:

我现在在评论中看到 a.grouped(2).map(_.reverse).flatten.toList。是的,这也有效,它与此相同但更不冗长,因为我们不是 "manually" 交换元素,而是对每个子列表执行 reverse

您还可以使用递归和模式匹配。这是有效的,因为您只浏览一次列表:

def changePairs(l: List[Int]): List[Int] = {
  l match {
    case a :: b :: tail => b :: a :: changePairs(tail)
    case _ => Nil
  }
}