Zip两个数组,总是第一个数组的3个元素,然后是第二个数组的2个元素

时间:2015-09-04 10:25:30

标签: scala functional-programming

我手动构建了一个带有2个数组的方法,并将它们组合成1个:

a0,a1,a2,b0,b1,a3,a4,a5,b2,b3,a6,...

所以我总是拿第一个数组中的3个元素,然后是第二个数组中的2个元素。 正如我所说,我手动构建了该功能。

现在我想我可以在zip的帮助下将其改为单行。问题是,单独的zip是不够的,因为zip构建了像(a0, b0)这样的元组。

当然我可以平坦地映射这个,但仍然不是我想要的:

val zippedArray: List[Float] = data1.zip(data2).toList.flatMap(t => List(t._1, t._2))

那样我会得到一个List(a0, b0, a1, b1,...),仍然不是我想要的。 (然后我使用toArray列表......现在使用List更方便)

我考虑过使用takedrop,但是他们会返回新的数据结构,而不是修改旧的数据结构,所以不是我想要的。

你可以想象,我还没有真正进入函数式编程。我确实使用它,我看到了巨大的好处,但有些事情与我以前的情况有很大不同。

2 个答案:

答案 0 :(得分:4)

考虑将数组a分组为3,将数组b分组为2,即

val a = Array(1,2,3,4,5,6)
val b = Array(11,22,33,44)

val g = (a.grouped(3) zip b.grouped(2)).toArray
Array((Array(1, 2, 3),Array(11, 22)), (Array(4, 5, 6),Array(33, 44)))

然后

g.flatMap { case (x,y) => x ++ y }
Array(1, 2, 3, 11, 22, 4, 5, 6, 33, 44)

答案 1 :(得分:2)

非常类似于@elm的答案,但我想表明你可以使用更懒惰的方法(迭代器)来避免创建临时结构:

scala> val a = List(1,2,3,4,5,6)
a: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> val b = List(11,22,33,44)
b: List[Int] = List(11, 22, 33, 44)

scala> val groupped = a.sliding(3, 3) zip b.sliding(2, 2)
groupped: Iterator[(List[Int], List[Int])] = non-empty iterator

scala> val result = groupped.flatMap { case (a, b) => a ::: b }
result: Iterator[Int] = non-empty iterator

scala> result.toList
res0: List[Int] = List(1, 2, 3, 11, 22, 4, 5, 6, 33, 44)

请注意,它一直保持迭代器,直到我们使用toList

实现它