Как свернуть 2D массив, удалив все пустые / пустые записи - PullRequest
0 голосов
/ 05 октября 2018

У меня есть 2D-контейнер с примерами данных, как показано ниже:

NULL  1
NULL  2
3     NULL
NULL  4
5     NULL

И я хочу свернуть вверх избавиться от всех пустых записей на пути, и результат будет похож на:

3     1
5     2
NULL  4

Можно ли это сделать функционально?Например, я могу подумать об использовании foldLeft для создания нового контейнера и добавления каждой строки вручную, но затем, когда я добавляю строки, ему все равно нужно использовать цикл for, чтобы найти следующее пустое место.Есть ли способ добиться этого?

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

Так как значение Int не может быть null, и в этом контексте внутренний тип массива будет иметь тип Array[Any] (не очень полезно), вместо этого я собираюсь использовать String, что можетbe 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))
0 голосов
/ 06 октября 2018

Согласно comment, указанному в ответе jwvh's, здесь приведена версия для большего количества столбцов:

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))
0 голосов
/ 05 октября 2018

Вы можете использовать фильтр для этого.В качестве примера я буду использовать кортежи, чтобы закончить следующим:

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

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

Первый сегмент содержит все элементы, в которых первый элемент кортежа не равен нулю, авторая часть переворачивает список, находит первый элемент, в котором «ключ» является нулем, и преобразует его в список, пустой, если элемент не найден, или список из одного элемента, если найдено совпадение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...