Scala问题:如何将List[Option[(A, List[B])]]转为Option[(A, List[B])]
问题解决
你的核心问题是原代码的for推导式错误地以List作为外层容器,导致返回List[Option[(A, List[B])]],而我们需要的是单一的Option[(A, List[B])]。下面是正确的实现方式:
正确实现方式1:使用Option.flatMap
def findRule(entryId: Option[String]): Option[(A, List[B])] = { entryId.flatMap { targetId => // 在rules中查找匹配元组:A的id存在且忽略大小写等于targetId rules.find { case (a, _) => a.id.exists(_.equalsIgnoreCase(targetId)) } } }
正确实现方式2:使用Option的for推导式
def findRule(entryId: Option[String]): Option[(A, List[B])] = { for { targetId <- entryId matchingRule <- rules.find { case (a, _) => a.id.exists(_.equalsIgnoreCase(targetId)) } } yield matchingRule }
原代码问题分析
原代码中第一个for生成器rules.flatMap(_._1.id)返回的是List[String],这直接把整个for推导式的结果类型固定为List,最终得到List[Option[(A, List[B])]]。而我们需要基于Option的容器特性来推导,所以应该把entryId作为第一个生成器,确保结果是单一的Option类型。
验证示例
假设定义:
case class A(id: Option[String]) case class B() val rules = List( (A(Some("1")), List(B(), B())), (A(Some("2")), List(B())) )
- 调用
findRule(Some("1")),返回Some((A(Some("1")),List(B(), B()))) - 调用
findRule(Some("3")),返回None - 调用
findRule(None),返回None
内容的提问来源于stack exchange,提问作者slowhand
相关产品推荐
相关产品推荐

