scala - 展平具有 Option[T] 值的地图
问题描述
我有一张地图,目前以类似的顺序表示Seq[(String, Option[T])]
。我不关心None
地图中的值,因为我想做一些操作,比如对它们进行排序,这样我就可以确定要使用哪个键。我可以做这样的事情:
val mapping: Seq[(String, Option[Foo])]
mapping.filter(_._2.isDefined)
.sortBy(_._2.get.someInt)
.headOption.map(_._1)
...但必须有更好的方法来写这个。特别是,这get
让我感到不舒服,因为该值仍然是 type Option[Foo]
,尽管其中不应该有任何None
值。
有没有更好的办法?
解决方案
Foo
我假设和有以下定义mapping
:
case class Foo(someInt: Int)
val mapping: Seq[(String, Option[Foo])] = Seq(("a", Some(Foo(42))), ("b", None))
你有几个选择:
collect
该collect
方法将模式匹配与过滤相结合:
mapping.collect{case (s,Some(Foo(i))) => (s,i) }.sortBy(_._2).headOption.map(_._1)
for
-yield
for
或者,您可以使用-达到相同的效果yield
,它也会抛出所有不匹配的元素:
(for ((s, Some(Foo(n))) <- mapping) yield(s, n)).sortBy(_._2).headOption.map(_._1)
O(N) 解决方案minBy
还要注意,为了提取最大值/最小值对整个集合进行排序是不必要的:有maxBy
/minBy
为此:
Option(for ((s, Some(Foo(n))) <- mapping) yield (s, n))
.filter(_.nonEmpty)
.map(_.minBy(_._2)._1)
将整个序列包装成Option
是必要的,这样我们就可以过滤掉序列为空的情况,因此我们不会minBy
在空序列上调用。
推荐阅读
- angular - 角'nativeElement'未定义
- reactjs - 映射双嵌套 JSON - React Child 中不允许的对象
- java - 使用 gradle 导入 mongodb - 产生无法解析符号 'mongodb'
- android - 从 google sheet 转换为 android strings file.xml
- android - 如何在多个片段中使用 TTS 实例?
- ruby-on-rails - 无法加载此类文件 -- webrick/httputils
- reactjs - getServerSideProps 访问当前浏览器 url
- python - 如何从代码而不是表单字段加载文件
- angular - 管道 rxjs 运算符如何可能受到后续运算符的返回值的影响?
- node.js - Windows_NT 10.0.18363