Как сгладить список различных типов в Scala?

У меня есть 4 элемента: List[List[Object]] (Объекты разные в каждом элементе), которые я хочу закрепить, чтобы иметь List[List[obj1],List[obj2],List[obj3],List[obj4]]

Я попытался их застегнуть, и я получил вложенный список, к которому я не могу применить flatten, потому что он говорит: неявный аргумент, соответствующий типу параметра.

Как я могу это решить? следует ли мне попробовать другой способ или есть способ сделать работу сглаживания?

Я новичок в scala, так что это может быть глупый вопрос: D Заранее спасибо! Clau

Ответ 1

Для одного вложенного списка: flatten будет делать:

scala> List(List(1), List(2), List(3)).flatten
res4: List[Int] = List(1, 2, 3)

scala> List(List(List(1)), List(List(2)), List(List(3))).flatten
res5: List[List[Int]] = List(List(1), List(2), List(3))

Для нескольких вложенных списков, вы можете:

def flatten(ls: List[Any]): List[Any] = ls flatMap {
  case i: List[_] => flatten(i)
  case e => List(e)
}

val k = List(1, List(2, 3), List(List(List(List(4)), List(5)), List(6, 7)), 8)
flatten(k)

Он печатает List[Any] = List(1, 2, 3, 4, 5, 6, 7, 8)

Ответ 2

До Scala 2.9

Из вставленной ошибки, похоже, вы пытаетесь вызвать метод экземпляра flatten самого вложенного списка. Для этого требуется неявное преобразование, чтобы сделать что-то типа Iterable из любых типов, содержащихся в списке. В вашем случае это похоже на то, что компилятор не может его найти.

Используйте flatten из объекта List singleton, который не требует наличия неявного параметра:

scala> val foo = List(List(1), List("a"), List(2.3))
foo: List[List[Any]] = List(List(1), List(a), List(2.3))

scala> List.flatten(foo)
res1: List[Any] = List(1, a, 2.3)

После Scala 2.9

Просто используйте foo.flatten.

Ответ 3

Вопрос очень расплывчатый. Вы должны просто вставить то, что у вас есть, а не пытаться описать его. Это сделало бы жизнь каждого (включая вашу) намного проще.

Ниже приведен один пример, основанный на предположении о том, что у вас есть.

scala> List(List(1))
res0: List[List[Int]] = List(List(1))

scala> List(List(2))
res1: List[List[Int]] = List(List(2))

scala> List(List(3))
res2: List[List[Int]] = List(List(3))

scala> List(List(4))
res3: List[List[Int]] = List(List(4))

scala> res0 ::: res1 ::: res2 ::: res3
res4: List[List[Int]] = List(List(1), List(2), List(3), List(4))

Ответ 4

В scala 2.10.2

scala> val foo = List(List(1), List("a"), List(2.3))
foo: List[List[Any]] = List(List(1), List(a), List(2.3))

scala> foo.flatten
res0: List[Any] = List(1, 2, a, 2.3)

работает нормально, но

если вы запустите, как

scala>  val foo = List(List(1,2), 2, List(2.3))
foo: List[Any] = List(List(1, 2), 2, List(2.3))

scala> foo.flatten
<console>:9: error: No implicit view available from Any => scala.collection.GenTraversableOnce[B].
              foo.flatten

для этого я пишу функцию

scala> def flat(ls: List[Any]): List[Any]= ls flatten {
     |   case t: List[Any] =>  flat(t)
     |   case c => List(c)
     | }   
flat: (ls: List[Any])List[Any]

scala> flat(List(List(1,2),2,List(2.3)))
res2: List[Any] = List(1, 2, 2, 2.3)

Ответ 5

Это помогает, если у нас есть пример. Ваш код должен выглядеть примерно так:

val f = List(1, 2)
val s = List(3, 4)
val top = List(f, s)

List.flatten(top) // returns List(1, 2, 3, 4)

Ответ 6

Вы можете зашивать только два списка одновременно с помощью list1 zip list2, а сигнатура типа для возвращаемых значений - List[(A,B)] not List[List[obj1],List[obj2],List[obj3],List[obj4]]

Ответ 7

Рассмотрим List.concat, например

List.concat(List(1), List(2,22), List(3))    // delivers List(1, 2, 22, 3)