Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

scala - Need to convert a Seq[Option[A]] to Option[Seq[A]]

USE CASE

I have a list of files that can might have a valid mime type or not. In my code, I represent this using an Option.

I need to convert a Seq[Option[T]] to Option[Seq[T]] so that I do not process the list if some of the files are invalid.

ERROR

This is the error in the implementation below:

found   : (Option[Seq[A]], Option[A]) => Option[Seq[A]]
[error]  required: (Option[Any], Option[Any]) => Option[Any]
[error]     s.fold(init)(liftOptionItem[A])

IMPLEMENTATION

def liftOptionItem[A](acc: Option[Seq[A]], itemOption: Option[A]): Option[Seq[A]] = {
    {
      acc match {
        case None => None
        case Some(items) =>
          itemOption match {
            case None => None
            case Some(item) => Some(items ++ Seq(item))
          }
      }
    }
  }

  def liftOption[A](s: Seq[Option[A]]): Option[Seq[A]] = {
    s.fold(Some(Seq()))(liftOptionItem[A])
  }

This implementation returns Option[Any] instead of Option[Seq[A] as the type of the liftOptionItem[A] does not fit in.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you use TypeLevel Cats:

import cats.implicits._

List(Option(1), Option(2), Option(3)).traverse(identity)

Returns:

Option[List[Int]] = Some(List(1, 2, 3))

You have to use List so use a toList first:

Seq(Option(1), Option(2), Option(3)).toList.traverse(identity).map(_.toSeq)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...