从 if/else 返回 seq

问题描述 投票:0回答:2

下面的假设示例 -

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
2个回答
0
投票

这是一个很好的例子,说明为什么 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 之间进行选择通常与条件的复杂性有关。


0
投票

尽管有其他详细而详尽的答案,但这是另一个选项,我认为最适合您的情况。

既然你问的问题是

目的是为书中存在的每个主题创建一个SubjectPack序列。

最好尝试直接回答:

subjects.filter(books.toSet).map(SubjectPack.apply)
© www.soinside.com 2019 - 2024. All rights reserved.