我正在尝试使用 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 获得正确的反转吗?
谢谢
a.grouped(2).flatMap(_.reverse).toArray
或者如果您需要 for/yield (在这种情况下要简洁得多,实际上扩展为相同的代码):
(for {b <- a.grouped(2); c <- b.reverse} yield c).toArray
如果你不使用它会更容易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)
我不知道 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 字节码。
另一个简单的收益解决方案:
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)
)
}
这是我的解决方案
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
我有我的解决方案,但没有收益。也许有人会发现它很有用。
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
}
如果你在 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) }
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
假设数组不为空,这里你去:
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)
}