将“任一列表”转换为“任一列表”的最佳方法?
我有一些如下所示的代码,其中有一个列表,我想将其转换为列表中的一个。特别是(在本例中),如果列表中有任何 Left,则返回它们列表的 Left,否则返回权利列表的 Right。
val maybe: List[Either[String, Int]] = getMaybe
val (strings, ints) = maybe.partition(_.isLeft)
strings.map(_.left.get) match {
case Nil => Right(ints.map(_.right.get))
case stringList => Left(stringList)
}
调用 get
总是让我觉得我一定错过了一些东西。
有没有更惯用的方法来做到这一点?
I have some code like the below, where I have a List of Eithers, and I want to turn it into an Either of Lists. In particular (in this case), if there are any Lefts in the list, then I return a Left of the list of them, otherwise I return a Right of the list of the rights.
val maybe: List[Either[String, Int]] = getMaybe
val (strings, ints) = maybe.partition(_.isLeft)
strings.map(_.left.get) match {
case Nil => Right(ints.map(_.right.get))
case stringList => Left(stringList)
}
Calling get
always makes me feel like I must be missing something.
Is there a more idiomatic way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
对于一趟:
For one pass:
从 Scala 2.13 开始,大多数集合现在都提供了
partitionMap
方法,根据返回Right
或Left
的函数对元素进行分区。在我们的例子中,我们甚至不需要将输入转换为
Right
或Left
的函数来定义分区,因为我们已经有了Right
s 和Left
s。这样就可以简单地使用身份
!然后,只需根据是否有左项来匹配左项和右项的分区元组即可:
为了理解
partitionMap
,这里是中间步骤的结果:Starting in
Scala 2.13
, most collections are now provided with apartitionMap
method which partitions elements based on a function returning eitherRight
orLeft
.In our case, we don't even need a function that transforms our input into
Right
orLeft
to define the partitioning since we already haveRight
s andLeft
s. Thus a simple use ofidentity
!Then it's just a matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are any lefts:
For the understanding of
partitionMap
here is the result of the intermediate step:Scala 书中的函数式编程的解决方案。
Solution from Functional Programming in Scala book.
您可以编写
split
的通用版本,如下所示:这样:
You can write a generalized version of
split
as follows:Such that:
我有点不希望有任何业力,因为它是 Chris 的答案 和 Viktor 来自 这里..但这里有一个替代方案:
示例:
I kind of don't want any karma for this as it's a merge of Chris's answer and Viktor's from here.. but here's an alternative:
Example:
如果您想要更通用且更实用的东西,那么您可能需要来自 cats 库的
Validated
类型。它类似于Either
,可以聚合错误。与NonEmptyList
结合使用,它的功能非常强大。http://typelevel.org/cats/datatypes/validated.html
If you want to have something more general and also functional then
Validated
from cats library is the type you might want. It is something likeEither
that can aggregate Errors. And in combination withNonEmptyList
it can be really powerful.http://typelevel.org/cats/datatypes/validated.html
难道不是更优雅的方式吗?
Isn't a more elegant way?
a :: acc
is a bullet-fastpartitionMap
, is probably faster, because of internal implementation based on builder分别提取左和右:
To extract Lefts and Rights separately: