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

1
  • 1
    Does the order matter? Does the types are always String or None? Commented Sep 29, 2015 at 18:16

4 Answers 4

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
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

The fold function can be { case (a, x) => (a, x).zipped map { case (y, z) => y orElse z } } where zipped avoids an intermediate collection.
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.

Comments

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)

2 Comments

Testing for None that way is especially stringly (i.e., bad). Bad as in awful.
@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.
2

For

val xs = List(list1,list2,list2)

consider

xs.flatten.distinct

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.