在scala中多次平铺大数组中的小数组
Tile a small Array in a large Array multiple times in scala
我想在一个大数组中多次平铺一个小数组。我正在寻找一种 "official" 方法来做到这一点。一个天真的解决方案如下:
val arr = Array[Int](1, 2, 3)
val array = {
val arrBuf = ArrayBuffer[Int]()
for (_ <- 1 until 10) {
arrBuf ++= arr
}
arrBuf.toArray
}
您可以使用 Array.fill
:
Array.fill(10)(Array(1, 2, 3)).flatten
如果您不知道为什么 阵列 对性能有好处 (意味着在这种情况下您并不真正需要原始性能) 我建议您不要使用它们,而是坚持使用 List 或 Vector。
数组不是正确的 Scala 集合,它们只是普通的 JVM 数组。意思是,它们是可变的,非常高效 (尤其是对于未装箱的基元),内存大小固定,并且非常受限。由于隐式转换和扩展方法,它们的行为类似于普通的 Scala 集合。但是,由于它们的可变性和不变性,你真的应该避免使用它们,除非你有充分的理由使用它们。
Andronicus 提出的解决方案对于数组来说并不理想(但对于任何真正的集合来说这将是一个非常好的解决方案) 因为给定的数组具有固定的内存大小,这种增肥将以不断的重新分配和引擎盖下的内存复制。
无论如何,这里是这种解决方案的一个细微变化,而是使用列表;这样效率更高一些。
implicit class ListOps[A](private val list: List[A]) extends AnyVal {
def times[B >: A](n: Int): List[B] =
Iterator.fill(n)(list).flatten.toList
}
List(1, 2, 3).times(3)
// res: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)
这里还有一个使用 2.13
中引入的新 ArraySeq 的高效版本;这是一个不可变数组。
(注意,你也可以使用普通数组来做到这一点)
implicit class ArraySeqOps[A](private val arr: ArraySeq[A]) extends AnyVal {
def times[B >: A](n: Int): ArraySeq[B] =
ArraySeq.tabulate(n * arr.lenght) { i => arr(i % arr.length) }
}
ArraySeq(1, 2, 3).times(3)
// res: ArraySeq[Int] = ArraySeq(1, 2, 3, 1, 2, 3, 1, 2, 3)
我想在一个大数组中多次平铺一个小数组。我正在寻找一种 "official" 方法来做到这一点。一个天真的解决方案如下:
val arr = Array[Int](1, 2, 3)
val array = {
val arrBuf = ArrayBuffer[Int]()
for (_ <- 1 until 10) {
arrBuf ++= arr
}
arrBuf.toArray
}
您可以使用 Array.fill
:
Array.fill(10)(Array(1, 2, 3)).flatten
如果您不知道为什么 阵列 对性能有好处 (意味着在这种情况下您并不真正需要原始性能) 我建议您不要使用它们,而是坚持使用 List 或 Vector。
数组不是正确的 Scala 集合,它们只是普通的 JVM 数组。意思是,它们是可变的,非常高效 (尤其是对于未装箱的基元),内存大小固定,并且非常受限。由于隐式转换和扩展方法,它们的行为类似于普通的 Scala 集合。但是,由于它们的可变性和不变性,你真的应该避免使用它们,除非你有充分的理由使用它们。
Andronicus 提出的解决方案对于数组来说并不理想(但对于任何真正的集合来说这将是一个非常好的解决方案) 因为给定的数组具有固定的内存大小,这种增肥将以不断的重新分配和引擎盖下的内存复制。
无论如何,这里是这种解决方案的一个细微变化,而是使用列表;这样效率更高一些。
implicit class ListOps[A](private val list: List[A]) extends AnyVal {
def times[B >: A](n: Int): List[B] =
Iterator.fill(n)(list).flatten.toList
}
List(1, 2, 3).times(3)
// res: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3)
这里还有一个使用 2.13
中引入的新 ArraySeq 的高效版本;这是一个不可变数组。
(注意,你也可以使用普通数组来做到这一点)
implicit class ArraySeqOps[A](private val arr: ArraySeq[A]) extends AnyVal {
def times[B >: A](n: Int): ArraySeq[B] =
ArraySeq.tabulate(n * arr.lenght) { i => arr(i % arr.length) }
}
ArraySeq(1, 2, 3).times(3)
// res: ArraySeq[Int] = ArraySeq(1, 2, 3, 1, 2, 3, 1, 2, 3)