【问题标题】:scala: complicated flatMap on a tuple of Optionsscala:选项元组上的复杂平面图
【发布时间】:2015-12-16 13:21:38
【问题描述】:

我的数据类型是:List[(Option[Set[Long]], Option[Set[(Long, Long)]])](即一个 2 元组选项的列表,一个用于一组 Long,一个用于一组 2 元组 Long)。例如:

val l = List((Option(Set(1L, 2L, 3L)), Option(Set((4L, 5L), (6L, 7L)))))

我希望将这个 List 平面映射为 List[Set[Long]] 类型,这样第二个选项的第一个元素中的每一个都将与第一个选项连接到一个新的 Set 上。所以这里想要的结果是:

List(Set(1L, 2L, 3L, 4L), Set(1L, 2L, 3L, 6L))

这适用于以下代码:

l.flatMap {
 case(setOpt1, setOpt2) =>
 val set1 = setOpt1.getOrElse(Set[Long]());
 val set2 = setOpt2.getOrElse(Set[(Long, Long)]());
 set2.map(k => set1 ++ Set(k._1))
 }

当第二个选项为None,第一个选项“存在”时,情节变厚,例如:

val l = List((Option(Set(1L, 2L, 3L)), None))

假设我无法避免这种情况。在这种情况下,我想按原样获取第一个 Set:

List(Set(1L, 2L, 3L))

但是,使用与上面相同的代码,set2 值变成了一个空 Set,而 map 在这种情况下没有任何意义,我会得到一个空 List:

res60: List[scala.collection.immutable.Set[Long]] = List()

那么,我该怎么做呢?最好优雅:)

【问题讨论】:

  • 您说明了(Some,Some)(Some,None) 应该发生什么。 (None,Some)(None,None) 呢?
  • (None, None)(None,Some) 都按预期工作:第一种情况返回空列表,第二种情况返回 List(Set(4L), Set(6L))

标签: scala option flatmap


【解决方案1】:

您可以添加 case 语句来处理Option 的每个组合

def g(l:List[(Option[Set[Long]], Option[Set[(Long, Long)]])]) = l.flatMap{
  case (Some(single), None) =>
    List(single)
  case (Some(single), Some(tuple)) =>
    tuple.map(k => single ++ Set(k._1))
  case (None, Some(tuple)) =>
    tuple.map(k => Set(k._1))
  case (None, None) =>
    List()

}

这会产生您期望的结果。以下是我运行的所有测试:

val l1 = List((Option(Set(1L, 2L, 3L)), Option(Set((4L, 5L), (6L, 7L)))))
g(l1)
res0: List[Set[Long]] = List(Set(1, 2, 3, 4), Set(1, 2, 3, 6))

val l2 = List((Option(Set(1L, 2L, 3L)), None))
g(l2)
res1: List[Set[Long]] = List(Set(1, 2, 3))

val l3 = List((None, Option(Set((4L, 5L), (6L, 7L)))))
g(l3)
res2: List[Set[Long]] = List(Set(4), Set(6))

val l4 = List((None, None))
g(l4)
res3: List[Set[Long]] = List()

【讨论】:

  • 但它不会产生第一个示例所需的结果:g(List((Option(Set(1L, 2L, 3L)), Option(Set((4L, 5L), (6L, 7L)))))) ~> res8: List[Iterable[Any]] = List(List(Set(1, 2, 3), 4), List(Set(1, 2, 3), 6))
  • @SvenKoschnicke 正确,在接受之前我没有看到。 narryddubbs 你能解决这个问题以保持接受吗?
  • @SvenKoschnicke 不错的收获。我更新了答案以纠正这个问题。
  • 我认为这里不需要flatMap,可以使用map
  • 不需要flatmap 在实现中
猜你喜欢
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2022-10-24
相关资源
最近更新 更多