如何用 Scala 中另一个 Seq 的值替换一个 Seq 中的值?
How to replace values in one Seq with values from another Seq in Scala?
我有序列:
val A = Seq(1,3,0,4,2,0,7,0,6)
val B = Seq(8,9,10)
我需要一个新序列,其中 0 替换为第二个序列中的值:
Seq(1,3,8,4,2,9,7,10,6)
如何以函数式风格做到这一点?
您可以在此处使用 map
,方法是将所有 0 替换为 b
的下一个元素(通过将 b
转换为迭代器,并使用 next
):
val a = Seq(1,3,0,4,2,0,7,0,6)
val b = Seq(8,9,10).iterator
a.map { e => if (e == 0) b.next else e } //Seq(1,3,8,4,2,9,7,10,6)
不确定迭代器是否真正起作用。无论如何,这是一个替代方案
val A = Seq(1,3,0,4,2,0,7,0,6)
val B = Seq(8,9,10)
A.foldLeft((B, Seq[Int]())) {case ((b, r), e) =>
if (e == 0 && ! b.isEmpty) (b.tail, b.head +: r) else (b, e +: r) }
._2.reverse
//> res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
编辑:如果我们没有 B
的元素,则根据评论进行更新以保留零
编辑 2:
模式匹配变体更简洁:
A.foldLeft((B, Seq[Int]())){case ((h +: t, r), 0) => (t, h +: r)
case ((b, r), e) => (b, e +: r)}
._2.reverse
并且,基于what is proper monad or sequence comprehension to both map and carry state across?
A.mapAccumLeft(B, { case ((h +: t), 0) => (t, h)
case (b, e) => (b, e) }
(可能,我没有安装 scalaz 来测试它)
如果您想了解尾递归,那么这很适合您。
@annotation.tailrec
def f(l1: Seq[Int], l2: Seq[Int], res: Seq[Int] = Nil): Seq[Int] = {
if (l1 == Nil) res
else {
if (l1.head == 0 && l2 != Nil) f(l1.tail, l2.tail, res :+ l2.head)
else
f(l1.tail, l2, res :+ l1.head)
}
}
val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
val B = Seq(8, 9, 10)
scala> f(A,B)
res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
如果你 运行 没有 B 中的元素那么 ,
val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
val B = Seq(8, 9)
scala> f(A,B)
res1: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 0, 6)
如果 A 中的元素小于 B 那么,
val A = Seq(1, 0)
val B = Seq(8, 9, 10)
scala> f(A,B)
res2: Seq[Int] = List(1, 8)
我有序列:
val A = Seq(1,3,0,4,2,0,7,0,6)
val B = Seq(8,9,10)
我需要一个新序列,其中 0 替换为第二个序列中的值:
Seq(1,3,8,4,2,9,7,10,6)
如何以函数式风格做到这一点?
您可以在此处使用 map
,方法是将所有 0 替换为 b
的下一个元素(通过将 b
转换为迭代器,并使用 next
):
val a = Seq(1,3,0,4,2,0,7,0,6)
val b = Seq(8,9,10).iterator
a.map { e => if (e == 0) b.next else e } //Seq(1,3,8,4,2,9,7,10,6)
不确定迭代器是否真正起作用。无论如何,这是一个替代方案
val A = Seq(1,3,0,4,2,0,7,0,6)
val B = Seq(8,9,10)
A.foldLeft((B, Seq[Int]())) {case ((b, r), e) =>
if (e == 0 && ! b.isEmpty) (b.tail, b.head +: r) else (b, e +: r) }
._2.reverse
//> res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
编辑:如果我们没有 B
的元素,则根据评论进行更新以保留零编辑 2:
模式匹配变体更简洁:
A.foldLeft((B, Seq[Int]())){case ((h +: t, r), 0) => (t, h +: r)
case ((b, r), e) => (b, e +: r)}
._2.reverse
并且,基于what is proper monad or sequence comprehension to both map and carry state across?
A.mapAccumLeft(B, { case ((h +: t), 0) => (t, h)
case (b, e) => (b, e) }
(可能,我没有安装 scalaz 来测试它)
如果您想了解尾递归,那么这很适合您。
@annotation.tailrec
def f(l1: Seq[Int], l2: Seq[Int], res: Seq[Int] = Nil): Seq[Int] = {
if (l1 == Nil) res
else {
if (l1.head == 0 && l2 != Nil) f(l1.tail, l2.tail, res :+ l2.head)
else
f(l1.tail, l2, res :+ l1.head)
}
}
val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
val B = Seq(8, 9, 10)
scala> f(A,B)
res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
如果你 运行 没有 B 中的元素那么 ,
val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
val B = Seq(8, 9)
scala> f(A,B)
res1: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 0, 6)
如果 A 中的元素小于 B 那么,
val A = Seq(1, 0)
val B = Seq(8, 9, 10)
scala> f(A,B)
res2: Seq[Int] = List(1, 8)