【问题标题】:How to collapse 2D array by eliminating all empty/null entries如何通过消除所有空/空条目来折叠二维数组
【发布时间】:2019-03-11 06:57:57
【问题描述】:

我有一个带有示例数据的 2D 容器,如下所示:

NULL  1
NULL  2
3     NULL
NULL  4
5     NULL

我想向上折叠去掉所有的 NULL 条目,结果如下:

3     1
5     2
NULL  4

这可以通过功能方式完成吗?例如。我可以考虑使用foldLeft来构造一个新的容器并手动添加每一行,但是当我添加行时,它仍然需要使用for循环来查找下一个空点。有什么方法可以实现吗?

【问题讨论】:

  • 这和java有什么关系?
  • @NicholasK 因为它可以用Java(或任何其他语言)实现?

标签: java algorithm scala functional-programming


【解决方案1】:

您可以为此使用过滤器。 为了示例的目的,我将使用元组,以便以以下方式结束:

val tuplesList = List( (null, 1), (null, 2), (3, null), (null, 4), (5, null))

tuplesList.filter(_._1 != null) :: tuplesList.reverse.find(_._1 == null).toList

第一段保留元组的第一个元素不为null的所有元素,而第二部分反转列表,找到“key”为null的第一个元素,并将其转换为List,如果没有找到任何元素,则为空;如果找到匹配项,则为单元素列表。

【讨论】:

  • tuplesListList[(Any, Any)] 类型,结果是 List[Product with Serializable]。很难从中提取有用的数据。
【解决方案2】:

由于Int 的值不能是null,并且在这种情况下它会使内部数组类型为Array[Any](不是很有用),我将使用String 代替,它可以是null

val container :Array[Array[String]] = Array(Array(null, "1")
                                           ,Array(null, "2")
                                           ,Array("3", null)
                                           ,Array(null, "4")
                                           ,Array("5", null))

val as = container.flatMap(s => Option(s(0)))
val bs = container.flatMap(s => Option(s(1)))
val res = as.zipAll(bs, null, null).map(t => Array(t._1, t._2))
//res: Array[Array[String]] = Array(Array(3, 1), Array(5, 2), Array(null, 4))

对于不同长度/宽度的二维数组,我们可以采用不同的方法。也许更复杂但也更安全,因为它对输入的假设更少。它必须是可转置的(所有行的长度相同)。如果container 为空,它甚至可以工作。

val container :Array[Array[String]] = Array(Array(null, "1", "6")
                                           ,Array(null, "2", null)
                                           ,Array("3", null, "7")
                                           ,Array(null, "4", "8")
                                           ,Array("5", null, "9"))

val collapsed = container.transpose.map(_.flatMap(Option(_)))
val maxLen = collapsed.foldLeft(0)(_ max _.length)
val res = collapsed.map(_.padTo(maxLen,null)).transpose
//res: Array[Array[String]] = Array(Array(3, 1, 6)
//                                 ,Array(5, 2, 7)
//                                 ,Array(null, 4, 8)
//                                 ,Array(null, null, 9))

【讨论】:

  • 如果列多于 2 列怎么办?
  • @texasbruce;看看我的补充。
【解决方案3】:

根据jwvh's答案中提到的comment,这里是 更多列数:

val container1 :Array[Array[String]] = Array(Array(null, "1")
                                           ,Array(null, "2")
                                           ,Array("3", null)
                                           ,Array(null, "4")
                                           ,Array("5", null))

val container2 :Array[Array[String]] = Array(Array(null, "1","7")
                                              ,Array(null, "2",null)
                                              ,Array("3", null,"8")
                                              ,Array(null, "4",null)
                                              ,Array("5", null,"6"))


 def collapseUpwards(con: Array[Array[String]]) = {
   val noNullArrays = con.map(s =>s.zipWithIndex.
                      map(s1=>Option( s(s1._2)))).transpose.map(_.flatten)
   val maxArraySize = noNullArrays.map(_.size).max
   noNullArrays.map(x=>x++Array.fill(maxArraySize-x.size)(null)).transpose
 }

测试

scala> collapseUpwards(container1)
res12: Array[Array[String]] = Array(Array(3, 1), Array(5, 2), Array(null, 4))

scala> collapseUpwards(container2)
res13: Array[Array[String]] = Array(Array(3, 1, 7), Array(5, 2, 8), Array(null, 4, 6))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2017-06-07
    • 2017-10-16
    • 2020-02-09
    • 1970-01-01
    • 2012-12-22
    相关资源
    最近更新 更多