0

I am new to Scala. I have three List.

List("XX", None,None,None)

List( None,"YY",None,None)

List(None,None,None, "ZZ")

I need to merge these list to create a single list which should look like

List("XX","YY",None,"ZZ")

Is there any way in scala to achieve this result? Thanks

elm
  • 20,117
  • 14
  • 67
  • 113
Amitabh Ranjan
  • 1,500
  • 3
  • 23
  • 39

4 Answers4

5

Maybe you need this?

val list: List[List[Option[String]]] = List(
  List(Some("XX"), None, None, None),
  List(None, Some("YY"), None, None),
  List(None, None, None, Some("ZZ"))
)
list.tail.foldLeft(list.head) {
  case (acc, item) => acc.zip(item).map {
    case (Some(x), _) => Some(x)
    case (_, y) => y
  }
}
Nyavro
  • 8,806
  • 2
  • 26
  • 33
  • 1
    The fold function can be `{ case (a, x) => (a, x).zipped map { case (y, z) => y orElse z } }` where zipped avoids an intermediate collection. – som-snytt Sep 29 '15 at 16:49
3

Your lists are List[AnyRef]. That's a type that should never appear in ordinary Scala code.

I would suggest representing your data using List[Option[String]]:

scala> List(List(Some("XX"), None, None, None),
     |      List(None, Some("YY"), None, None),
     |      List(None, None, None, Some("ZZ")))
res2: List[List[Option[String]]] = List(...

Now your problem is easy to solve:

scala> res2.transpose.map(_.flatten.headOption)
res6: List[Option[String]] = List(Some(XX), Some(YY), None, Some(ZZ))

I've assumed here that if there are multiple Somes in the same position, you want to take the first one.

Seth Tisue
  • 29,985
  • 11
  • 82
  • 149
2
val l1 = List("XX", None, None, None)
val l2 = List(None, "YY", None, None)
val l3 = List(None, None, None, "ZZ")

val listOfList = List(l1, l2, l3) 

// Assuming all lists are of same length.

val lT = listOfList.transpose  // swap column and rows
val result = lT.map{ _.reduce{ (a, b) => 
  if (a.toString == "None") b else a
}}
// List[Serializable] = List(XX, YY, None, ZZ)
Shyamendra Solanki
  • 8,751
  • 2
  • 31
  • 25
  • Testing for `None` that way is especially stringly (i.e., bad). Bad as in awful. – som-snytt Sep 29 '15 at 16:35
  • @som-snytt point accepted. but starting from given data, its a way to achieve the result. others have made the point that starting place should be List of options. I agree. – Shyamendra Solanki Sep 29 '15 at 16:40
2

For

val xs = List(list1,list2,list2)

consider

xs.flatten.distinct
elm
  • 20,117
  • 14
  • 67
  • 113