8

我正在尝试使用 for 和 yield 交换数组中的每一对值,但到目前为止我非常不成功。我尝试过的如下:

val a = Array(1,2,3,4,5) //What I want is Array(2,1,4,3,5)

for(i<-0 until (a.length-1,2),r<- Array(i+1,i)) yield r

上面给出的片段返回向量 2,1,4,3(省略了 5)

有人可以指出我在这里做错了什么以及如何使用 for 和 yield 获得正确的反转吗?

谢谢

4

9 回答 9

40
a.grouped(2).flatMap(_.reverse).toArray

或者如果您需要 for/yield (在这种情况下要简洁得多,实际上扩展为相同的代码):

(for {b <- a.grouped(2); c <- b.reverse} yield c).toArray
于 2012-04-15T06:39:40.540 回答
17

如果你不使用它会更容易for/yield

a.grouped(2)
  .flatMap{ 
    case Array(x,y) => Array(y,x)
    case Array(x) => Array(x)
  }.toArray // Array(2, 1, 4, 3, 5)
于 2012-04-15T00:19:12.163 回答
9

我不知道 OP 是否正在为 Impatient 阅读 Scala,但这是练习 3.3 。

我喜欢地图解决方案,但我们还没有讨论那一章,所以这是我使用所需的 for/yield 的丑陋实现。您可能可以将一些收益逻辑移动到保护/定义中。

for( i <- 0 until(a.length,2); j <- (i+1).to(i,-1) if(j<a.length) ) yield a(j)

我是一个 Java 人,所以我没有确认这个断言,但我很好奇地图/分组和迭代器的开销是什么。我怀疑这一切都编译成相同的 Java 字节码。

于 2014-01-28T21:58:01.073 回答
1

另一个简单的收益解决方案:

def swapAdjacent(array: ArrayBuffer[Int]) = {
    for (i <- 0 until array.length) yield (
        if (i % 2 == 0)
            if (i == array.length - 1) array(i) else array(i + 1)
        else array(i - 1)
    )
}
于 2014-03-17T09:17:46.743 回答
0

这是我的解决方案

  def swapAdjacent(a: Array[Int]):Array[Int] =
    (for(i <- 0 until a.length) yield
      if (i%2==0 && (i+1)==a.length) a(i) //last element for odd length
      else if (i%2==0) a(i+1)
      else a(i-1)
    ).toArray

https://github.com/BasileDuPlessis/scala-for-the-impatient/blob/master/src/main/scala/com/basile/scala/ch03/Ex03.scala

于 2014-05-20T16:06:34.843 回答
0

我有我的解决方案,但没有收益。也许有人会发现它很有用。

def swap(x: Array[Int]): Array[Int] = {
    for (i <- 0 until x.length-1 by 2){
      var left = x(i)
      x(i) = x(i+1)
      x(i+1) = left
    }
    x
  }
于 2017-01-11T20:32:46.770 回答
0

如果你在 Scala 中为不耐烦的人做练习 3.2 和 3.3,这两个都是我的答案。它们与移动的逻辑相同。

/** Excercise 3.2 */
for (i <- 0 until a.length if i % 2 == 1) {val t = a(i); a(i) = a(i-1); a(i-1) = t }
/** Excercise 3.3 */
for (i <- 0 until a.length) yield { if (i % 2 == 1) a(i-1) else if (i+1 <= a.length-1) a(i+1) else a(i) }
于 2015-10-07T17:06:54.480 回答
0
for (i <- 0 until arr.length-1 by 2) { val tmp = arr(i); arr(i) = arr(i+1); arr(i+1) = tmp }

我最近开始学习 Scala,Scala for the Impatient (1st edition) 一书中的所有解决方案都可以在我的 github 上找到:

第 2 章 https://gist.github.com/carloscaldas/51c01ccad9d86da8d96f1f40f7fecba7

第 3 章 https://gist.github.com/carloscaldas/3361321306faf82e76c967559b5cea33

于 2016-09-26T19:48:08.453 回答
0

假设数组不为空,这里你去:

val swapResult = for (ind <- arr1.indices) yield {
  if (ind % 2 != 0) arr1(ind - 1)
  else if (arr1(ind) == arr1.last) arr1(ind)
  else if (ind % 2 == 0) arr1(ind + 1)
}
于 2021-02-14T00:46:50.847 回答