【问题标题】:Find an element in a list in Scala在 Scala 中查找列表中的元素
【发布时间】:2017-04-27 19:38:14
【问题描述】:

我正在尝试编写一个函数 myfoo,它采用一个 Int 和一个 int 列表来验证 int 元素是否在列表中。如果 int 在列表中,它应该返回“true”,否则返回 false。 我已经写了这个函数,但是当我编译它时它返回这个错误:

error: type mismatch;    
 found   : Unit   
 required: Boolean    
        breakable { for  (i <-l) {   
                          ^
one error found*   

这是我的程序:

import scala.util.control.Breaks._

object findEl extends App{
    def myfoo (x:Int,l:List[Int]):Boolean={
        breakable { for  (i <-l) {
        i match {
            case a if (a==x) => true
            case _ => false
            break
            } 
        }
    }
}

    println(myfoo(1,List(1,2,3,4))) //should print "true"
}

我该如何解决? :)

【问题讨论】:

  • 我必须使用必要的“匹配”结构来锻炼!
  • 您是否在任何地方指定了“易碎”??
  • 你也必须使用breakable吗?如果没有,你应该匹配l,并且没有任何for
  • @Pierfrancesco 请不要在您的问题标题中将“SCALA”大写。这非常令人分心。这是我在 2 个帖子中的 第二次 出于这个原因编辑您的标题。

标签: scala list pattern-matching


【解决方案1】:

这就是breakable的实现方式

def breakable(op: => Unit) {
  try {
    op
  } catch {
    case ex: BreakControl =>
      if (ex ne breakException) throw ex
  }
}

Breakable 最终返回Unit。所以这就是编译器抱怨的原因。

这是解决此问题的一种方法。注意我使用的是var

import scala.util.control.Breaks._

  object findEl extends App {
    def myfoo(x: Int, l: List[Int]): Boolean = {
      var res: Boolean = false
      breakable {
        for (i <- l) {
          i match {
            case a if a == x => res = true
              break
            case _ => ()
          }
        }
      }
      res
    }

    println(myfoo(1, List(1, 2, 3, 4))) //should print "true"
  }

实现相同的功能方式(更好的方式)

 def myFoo(num: Int, list: List[Int]): Boolean = list match {
    case Nil => false
    case `num` :: xs => true
    case _  => myFoo(num, list.tail)
  }

以下代码相同,但不使用反引号

def myFoo(num: Int, list: List[Int]): Boolean = list match {
    case Nil => false
    case x :: xs if x == num => true
    case _  => myFoo(num, list.tail)
  }

Scala REPL

scala>  def myFoo(num: Int, list: List[Int]): Boolean = list match {
     |     case Nil => false
     |     case `num` :: xs => true
     |     case _  => myFoo(num, list.tail)
     |   }
myFoo: (num: Int, list: List[Int])Boolean

scala> myFoo(1, List(2, 1, 2))
res0: Boolean = true

使用 breakable 不是功能实践

使用异常停止程序的执行是无效的。函数式编程提倡通过类型解释进行通信。内部可中断通过抛出异常来停止控制流。 以上第二种方式是从功能上解决问题的方式。

【讨论】:

  • 得到它!那么没有办法使用breakable来实现这段代码吗?
  • @Pierfrancesco 检查
  • 非常感谢您的解决方案! :)
  • 只是好奇,你为什么在num 周围使用反引号?我的代码在没有它们的情况下运行。
  • @evan058 反引号将尝试将变量 num 的值与列表头的值匹配。如果没有反引号,您需要进行比较,例如 x :: xs if num == x
【解决方案2】:

你可以改用这个技巧

def function myFoo(x:Int, xList:List[Int]) = xList.contains(x)

println(myFoo(1, List(1,2,3,4,5,6)))

【讨论】:

    猜你喜欢
    • 2013-11-21
    • 2013-07-26
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2021-06-06
    • 2019-03-25
    • 2011-01-12
    相关资源
    最近更新 更多