首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >partialFunction in collectFirst

partialFunction in collectFirst
EN

Stack Overflow用户
提问于 2021-06-17 09:47:43
回答 2查看 182关注 0票数 1

我有一些对象的序列,我想收集第一个元素,其中另一个函数返回了一些()

现在,我的代码是这样工作的:

代码语言:javascript
复制
mySeq.collectFirst{
  case elem if doSmth(elem).nonEmpty => 
    (doSmth(elem).get, elem)
}

有没有办法:

  1. 重构它不调用doSmth两次?

  1. 将此代码更改为日志smth,以防doSmth不返回

代码语言:javascript
复制
res.match {
  case Some(v) => v
  case None => log.info("Searching further...")//partial function doesn't match
}

我要说的是,主要的问题是--是否有可能创建一个匹配所有情况的PartialFunction,但是对于某些情况,我们确实会产生一些副作用(在这种情况下会产生日志消息),并明确地说它是不匹配的?

编辑:

我想知道,当我运行测试时,为什么下面的代码会抛出一个错误(但不是编译错误)

代码语言:javascript
复制
mySeq.collectFirst{
case elem => 
  val r: Option[Int] = doSmth(elem)
  r match {
    case Some(res) => res
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-17 12:16:52

是的,可能有一种方法可以避免两次调用doSmth并记录空值,但这看起来非常糟糕(您必须显式地对PartialFunction进行子类处理,拼出isDefined,并有一个var成员来保存结果)。

总的来说,这对collectFirst来说不是一个好的用例。就像这样做吧:

代码语言:javascript
复制
   mySeq
     .view
     .map(doSmth)
     .flatMap { 
       case None => 
         log("nope")
         None
       case x => x
     }.headOption

或者,如果您和我一样,并且喜欢将一系列简短的转换链接到一个单块函数上,那么这里有一种奇特的方法:

代码语言:javascript
复制
   mySeq
    .view
    .map(doSmth)
    .map(_.toRight(println("searching")))
    .collectFirst { case Right(x) => x }
票数 4
EN

Stack Overflow用户

发布于 2021-06-17 17:30:08

您可以为此使用自定义模式匹配器。这是一个具有unapply方法的对象,可以在模式匹配中使用。

此代码将执行与原始代码相同的操作,但只调用一次doSmth

代码语言:javascript
复制
object MatchSomething {
  def unapply[T](elem: T): Option[(String, T)] =
    doSmth(elem).map(r => (r, elem))
}

mySeq.collectFirst {
  case MatchSomething((smth, elem)) =>
    (smth, elem)
}

可以在unapply方法中记录失败的匹配:

代码语言:javascript
复制
object MatchSomething {
  def unapply[T](elem: T): Option[(String, T)] =
    doSmth(elem) match {
      case Some(r) =>
        Some((r, elem))
      case None =>
        println(s"$elem did not match, searching further")
        None
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68016874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档