加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 你如何在达到第一个没有时停止构建Option [Collection]

发布时间:2020-12-16 09:25:06 所属栏目:安全 来源:网络整理
导读:在Option中构建集合时,每次尝试创建集合的下一个成员都可能会失败,从而使集合整体失败.在第一次没有成为会员时,我想立即放弃并返回整个收集的无.在Scala中执行此操作的惯用方法是什么? 这是我提出的一种方法: def findPartByName(name: String): Option[Pa
在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循环更清晰.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读