如何将嵌套数组转换为扁平化数组?

3
我有一个嵌套数组:Array("AA", Array("BB", "CC"), "DD")。我该如何在Scala中将其转换为:Array("AA", "BB", "CC", "DD")
谢谢您的帮助!

谢谢所有的答案!我非常感激它们。我注意到我犯了一个错误。我的数据实际上是这样的:Array((AA, Array(BB, CC), DD))。下面给出的示例答案(arr.flatMap)会导致类型不匹配。抱歉,我是Scala的新手。看起来像是一个包含嵌套数组的元组数组。在这种情况下,我仍然想要格式为:Array((AA, BB, CC, DD))。有什么想法吗?非常感谢! - wdz
3个回答

2

首先检查数组的推断类型:

scala> val arr = Array("AA", Array("BB", "CC"), "DD")
arr: Array[java.io.Serializable] = Array(AA, Array(BB, CC), DD)

Scala的集合对于它们的元素只有一个类型,因此如果您将字符串和字符串数组(或字符串数组的数组)放入数组中,您最终会得到一个元素类型是两者共享的最具体类型的数组——在这种情况下,是Serializable,这相当无用,因为要对数组元素执行任何操作,您都需要将它们转换为其他类型。
因此,最好一开始就不要让自己陷入这种情况。如果您不在集合中混合不相关的内容,那么类型系统会更加强大。尽管如此,如果您确实必须这样做,可以编写以下内容:
def flattenStringArrays[A](arr: Array[A]): Array[String] =
  arr.flatMap {
    case s: String => Array(s)
    case a: Array[_] => flattenStringArrays(a)
  }

然后:

scala> flattenStringArrays(arr)
res0: Array[String] = Array(AA, BB, CC, DD)

或者如果您“知道”您只会有一个嵌套层级:

scala> arr.flatMap {
     |   case s: String => Array(s)
     |   case a: Array[String] => a
     | }
res1: Array[String] = Array(AA, BB, CC, DD)

但这两种方法都不安全,而且非常不符合惯用语。

0
array.flatMap {
    case x: Array[_] => x
    case y => List(y)
}

1
嗯,我已经提供了这个确切的解决方案(但没有混淆ListArray的困惑)。 - Travis Brown
这不是一个完美的解决方案,但绝对不会像-1那样糟糕。一个合适的解决方案应该是没有List的。 - Matias Saarinen
@TravisBrown,我在回答之前没有看过你的答案,它有效而且简短。仅仅因为你写了类似的东西就给它投反对票并不好,这不是一场比赛。 - Kaan Dedeoglu
@MatiasSaarinen 这并不完美,并且无法处理两层深度嵌套。 - Kaan Dedeoglu
毫不个人化——我会 downvote 我注意到的任何仅包含代码的答案,尤其在这种情况下需要很多上下文才能得到有用的答案。 - Travis Brown
@TravisBrown 没关系,谢谢你的解释。 - Kaan Dedeoglu

-1

以下是使用foldLeft和一些模式匹配的版本:(它不保留原始顺序)

$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.

scala>   val container = Array("AA", Array("BB", "CC"), "DD")
container: Array[java.io.Serializable] = Array(AA, Array(BB, CC), DD)

scala>   container.foldLeft(Array.empty[String]) { (memo, next) =>
     |     next match {
     |       case s: String => s +: memo
     |       case arr: Array[_] => arr.map(_.toString) ++ memo
     |     }
     |   }
res0: Array[String] = Array(DD, BB, CC, AA)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接