下面的假设示例 -
val subjects = Seq("Physics","Maths","English","Chemistry")
val books = Seq("Physics", "English")
val registeredsubjects = subjects.map{ case( subject) =>
If(books.contains(subject))
SubjectPack(subject)
else None}.toseq
由于
else
部分,此代码将无法编译。
目的是为书中存在的每个主题创建一系列
SubjectPack
。
我该如何实现这一点?
这是一个很好的例子,说明为什么 Scala 的标准库很棒,恕我直言!
您大约有 3 种可能的选择:
1/ 使用
map
+ filter
的“幼稚”方法。不要使用它。只是为了展示“心路”。
val registeredsubjects = subjects
.map { case subject =>
if (books.contains(subject)) Some(SubjectPack(subject))
else None
}
.filter(_.isDefined)
.map(_.get) // safe thanks to the filter above
2/使用
collect
。当您看到 map
+filter
时,您需要告诉自己 filter
可能可以一次性替换 2 个操作。
val registeredsubjects = subjects
.map { case subject =>
if (books.contains(subject)) Some(SubjectPack(subject))
else None
}
.collect { case Some(pack) => pack }
但实际上您甚至可以通过移动匹配中的条件来合并第一个
map
:
val registeredsubjects = subjects
.collect { case subject if (books.contains(subject)) =>
SubjectPack(subject)
}
3/ 最后,您可以受益于以下事实:
Option
也是 Seq
(零或 1 项)并使用 flatMap
:
val registeredsubjects = subjects
.flatMap { case subject =>
if (books.contains(subject)) Some(SubjectPack(subject))
else None
}
在 2 和 3 之间进行选择通常与条件的复杂性有关。
尽管有其他详细而详尽的答案,但这是另一个选项,我认为最适合您的情况。
既然你问的问题是
目的是为书中存在的每个主题创建一个SubjectPack序列。
最好尝试直接回答:
subjects.filter(books.toSet).map(SubjectPack.apply)