如何使用高阶函数展平选项列表? [英] How to flatten list of options using higher order functions?

查看:34
本文介绍了如何使用高阶函数展平选项列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Scala 2.7.7:

如果我有一个选项列表,我可以使用 for-comprehension 将它们展平:

val listOfOptions = List(None, Some("hi"), None)listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)标度>for (opt <- listOfOptions; string <- opt) 产生字符串res0: List[java.lang.String] = List(hi)

我不喜欢这种风格,宁愿使用 HOF.这种尝试过于冗长,无法接受:

scala>listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None)res1: List[java.lang.String] = List(hi)

直觉上,我希望以下内容有效,但事实并非如此:

scala>List.flatten(listOfOptions)<console>:6: 错误:类型不匹配;找到:列表[选项[java.lang.String]]要求:列表[列表[?]]List.flatten(listOfOptions)

即使以下看起来应该有效,但没有:

scala>listOfOptions.flatMap(_: Option[String])<console>:6: 错误:类型不匹配;找到:选项[字符串]要求:(Option[java.lang.String]) =>可迭代[?]listOfOptions.flatMap(_: Option[String])^

我能想到的最好的是:

scala>listOfOptions.flatMap(_.toList)res2: List[java.lang.String] = List(hi)

...但我宁愿不必将选项转换为列表.这看起来很笨重.

有什么建议吗?

解决方案

在 Scala 2.8 中,flatten 将起作用:

<预><代码>欢迎使用 Scala 版本 2.8.0.RC2(Java HotSpot(TM) 64 位服务器 VM,Java 1.6.0_20).输入表达式以对它们进行评估.输入 :help 以获取更多信息.scala> val listOfOptions = List(None, Some("hi"), None)listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)Scala> listOfOptions 展平res0: List[java.lang.String] = List(hi)

这在 2.7.7 中不起作用,但是:

<预><代码>欢迎使用 Scala 版本 2.7.7.final(Java HotSpot(TM) 64 位服务器 VM,Java 1.6.0_20).Scala> val listOfOptions = List(None, Some("hi"), None)listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)Scala> listOfOptions.flatten:6: 错误: 没有隐式参数匹配参数类型 (Option[java.lang.String]) => Iterable[Nothing] 被发现.listOfOptions.flatten

集合库已经过重新设计,并且在 2.8 中得到了很大改进,所以也许您可能想尝试使用最新的 Scala 2.8 RC,看看它是否让您更容易使用.

如果你实在不想用toList方法,我猜你也可以这样写:

<预><代码>Scala> listOfOptions.flatMap(o => o)res: List[java.lang.String] = List(hi)

也许也不是什么美丽的东西,但至少这在 2.7.7 中有效.

Using Scala 2.7.7:

If I have a list of Options, I can flatten them using a for-comprehension:

val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> for (opt <- listOfOptions; string <- opt) yield string
res0: List[java.lang.String] = List(hi)

I don't like this style, and would rather use a HOF. This attempt is too verbose to be acceptable:

scala> listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None)
res1: List[java.lang.String] = List(hi)

Intuitively I would have expected the following to work, but it doesn't:

scala> List.flatten(listOfOptions)
<console>:6: error: type mismatch;
 found   : List[Option[java.lang.String]]
 required: List[List[?]]
       List.flatten(listOfOptions)

Even the following seems like it should work, but doesn't:

scala> listOfOptions.flatMap(_: Option[String])
<console>:6: error: type mismatch;
 found   : Option[String]
 required: (Option[java.lang.String]) => Iterable[?]
       listOfOptions.flatMap(_: Option[String])
                          ^

The best I can come up with is:

scala> listOfOptions.flatMap(_.toList)         
res2: List[java.lang.String] = List(hi)

... but I would much rather not have to convert the option to a list. That seems clunky.

Any advice?

解决方案

In Scala 2.8, flatten will work:


Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> listOfOptions flatten
res0: List[java.lang.String] = List(hi)

This doesn't work in 2.7.7, however:


Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).

scala> val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)

scala> listOfOptions.flatten
:6: error: no implicit argument matching parameter type (Option[java.lang.String]) => Iterable[Nothing] was found.
       listOfOptions.flatten

The collections library has been redesigned, and has improved a lot in 2.8, so perhaps you might want to try to use the latest Scala 2.8 RC and see if that makes it more easy to use for you.

If you really don't want to use the toList method, I guess you can also write it like this:


scala> listOfOptions.flatMap(o => o)
res: List[java.lang.String] = List(hi)

Also not a thing of beauty perhaps, but at least this works in 2.7.7.

这篇关于如何使用高阶函数展平选项列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆