【问题标题】:Scala: subtract index of odd valuesScala:减去奇数值的索引
【发布时间】:2017-04-19 07:01:42
【问题描述】:

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

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);
} 

【问题讨论】:

  • 不清楚您要做什么。如果您只想更改奇数值的索引,为什么要在第二个示例中移动 46
  • 我不明白你的逻辑。您的第二个示例只有两个奇数值(7 和 9),但更改的值远不止这两个值。
  • a.grouped(2).map(_.reverse).flatten.toList这个问题前几天才问过,但是找不到骗子。
  • @CyrilleCorpet 刚刚注意到我写错了,不是每个奇数值,而是奇数索引中的每个值。
  • @JörgWMittag 就像我对 CyrilleCorpet 说的一样,我解释得很糟糕,不是奇数,而是奇数索引处的值。

标签: scala patch


【解决方案1】:

这是一种方法:

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 获得的迭代器。

编辑:

我现在在 cmets 中看到了 a.grouped(2).map(_.reverse).flatten.toList。是的,这也行得通,它与 this 相同,但不那么冗长,因为我们不是“手动”交换元素,而是在每个子列表上执行 reverse

【讨论】:

  • 使用两个答案中最好的一个:a.grouped(2).flatMap(_.reverse).toList。当你在玩code golf 时,每一杆都很重要。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多