首页 > 解决方案 > Unflatten a flat array in Scala

问题描述

I have a flat array like this and another flat array that describes the dimensions:

val elems = Array(0,1,2,3)
val dimensions = Array(2,2)

So now I must be able to unflatten that and return a 2*2 array like this:

val unflattened = {{0,1},{2,3}}

The dimensions could be of any order. The only condition is that the length of the flat array will equal to the product of the dimensions. So for example., if the dimensions is

Array(3,3)

then I expect that the elems flat array will have to have 9 elements in it! The preconditions will be checked elsewhere so I do not have to worry about it here! All I need to do is to return an unflattened array.

Since this has to work on any dimension size, I think I probably have to define a recursive structure to put my results! Something like this?

case class Elem(elem: Array[Elem])

Could this work?

Any clue on how to go about implementing this function?

标签: arraysscalarecursionmultidimensional-array

解决方案


这是一个解决方案:

def unflatten(flat: Vector[Any], dims: Vector[Int]): Vector[Any] =
  if (dims.length <= 1) {
    flat
  } else {
    val (Vector(dim), rest) = dims.splitAt(1)

    flat.grouped(flat.length/dim).map(a => unflatten(a, rest)).toVector
  }

我使用过Vector是因为Array它不是真正的 Scala 类型,并且不允许从 转换Array[Int]Array[Any].

请注意,这仅实现了具有给定尺寸的可能分区之一,因此它可能是也可能不是所需的。


这是一个使用基于Matrix另一个答案中的特征的类型的版本:

trait Matrix
case class SimpleMatrix(rows: Vector[Int]) extends Matrix
case class HigherMatrix(matrices: Vector[Matrix]) extends Matrix

def unflatten(flat: Vector[Int], dims: Vector[Int]): Matrix =
  if (dims.length <= 1) {
    SimpleMatrix(flat)
  } else {
    val (Vector(dim), rest) = dims.splitAt(1)

    val subs = flat.grouped(flat.length/dim).map(a => unflatten(a, rest)).toVector

    HigherMatrix(subs)
  }

推荐阅读