Search code examples
scalascala-cats

Scala: filtering list of tuples to get a nonEmptyList


I have a list of the type List[(A, List[B])]. I want to flatten this structure and get:

  • NonEmptyList[A] consisting of all the Acorresponding to a nonEmpty List[B].

  • all those Bs combined: NonEmptyList[B]

ie, I want to get Option[(NonEmptyList[A], NonEmptyList[B])]. What is the most concise way of doing this.


Solution

  • Untested, but using definitions from the comments, this should work:

    for {
      a <- NonEmptyList.fromList(list.collect{ case (a, _::_) => a })
      b <- NonEmptyList.fromList(list.flatMap(_._2))
    } yield (a, b)
    

    This also has the advantage of avoiding the second computation if the first returns None.


    Previous versions:

    val listA = list.collect{ case (a, _::_) => a }
    val listB = list.flatMap(_._2)
    
    listA.headOption.flatMap(listB.headOption.map(_ => (NonEmptyList(listA), NonEmptyList(listB))))
    

    Another version might be

    (listA, listB) match {
      case (_::_, _::_) =>
        Some(NonEmptyList(listA), NonEmptyList(listB))
      case _ =>
        None
    }