scala – 你如何在达到第一个没有时停止构建Option [Collection]
在Option中构建集合时,每次尝试创建集合的下一个成员都可能会失败,从而使集合整体失败.在第一次没有成为会员时,我想立即放弃并返回整个收集的无.在Scala中执行此操作的惯用方法是什么?
这是我提出的一种方法: def findPartByName(name: String): Option[Part] = .?.?. def allParts(names: Seq[String]): Option[Seq[Part]] = names.foldLeft(Some(Seq.empty): Option[Seq[Part]]) { (result,name) => result match { case Some(parts) => findPartByName(name) flatMap { part => Some(parts :+ part) } case None => None } } 换句话说,如果对findPartByName的任何调用返回None,则allParts返回None.否则,allParts返回包含部分集合的Some,所有部分都保证有效.空集合是可以的. 上面的优点是它在第一次失败后停止调用findPartByName.但是,无论如何,foldLeft仍会为每个名称迭代一次. 这是一个版本,一旦findPartByName返回None,就会挽救: def allParts2(names: Seq[String]): Option[Seq[Part]] = Some( for (name <- names) yield findPartByName(name) match { case Some(part) => part case None => return None } ) 我目前发现第二个版本更具可读性,但是(a)看起来最具可读性的东西可能随着我获得Scala的更多经验而改变,(b)我得到的印象是早期的回归在Scala中不受欢迎,并且(c)两者都没有一个似乎对我来说特别明显的事情. “全有或无”和“放弃第一次失败”的组合看起来像是一个基本的编程概念,我认为必须有一个共同的Scala或功能成语来表达它. 解决方法
代码中的返回实际上是匿名函数中的几个级别.因此,必须通过抛出外部函数中捕获的异常来实现它.这不高效或漂亮,因此皱着眉头.
使用while循环和迭代器编写它是最简单和最有效的. def allParts3(names: Seq[String]): Option[Seq[Part]] = { val iterator = names.iterator var accum = List.empty[Part] while (iterator.hasNext) { findPartByName(iterator.next) match { case Some(part) => accum +:= part case None => return None } } Some(accum.reverse) } 因为我们不知道Seq名称是什么类型,所以我们必须创建一个迭代器来有效地循环它,而不是使用尾部或索引. while循环可以用尾递归内部函数替换,但是使用迭代器,while循环更清晰. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 免费 webservice 收集
- 配置 – 如何使用bdb后端配置OpenLDAP 2.4?
- Scala集合,单键多值
- 基于Bootstrap下拉框插件bootstrap-select使用方法详解
- 跟我学AngularJs:AngularJs入门及第一个实例
- Angular TypeError:在尝试调用object.object [].方法时不是
- angularjs – ng-change事件未在bootstrap模式中为文本输入
- 打开LDAP vs apacheDS
- angularjs – $routeProvider.when中的控制器vs模板中的ng-
- WebService学习之Axis2(1):用POJO实现0配置的WebService