【问题标题】:How to break/escape from a for loop in Scala?如何打破/退出Scala中的for循环?
【发布时间】:2015-07-04 18:05:59
【问题描述】:

我是 scala 的新手,并且搜索了很多解决方案。 我正在查询数据库并将解析为 json4s 对象的 http 请求的值作为响应存储。我等待响应并解析 json。

val refService = url("http://url//)
val response = Http(refService OK dispatch.as.json4s.Json)
var checkVal :Boolean = true
val json = Await.result(response, 30 seconds)

val data = json \ "data"

我想运行一个循环并检查“name”的值是否存在于返回的数据中。如果存在,我想打破并将 checkVal 分配给 false。到目前为止,我有这个:

for {
  JObject(obj) <- data
 JField("nameValue", JString(t)) <- obj //nameValue is the column name in the returned data
  } yield {checkVal= if (t == name){ break }
 else 
   true
  }

Eclipse 给我以下错误:类型不匹配;找到:需要列表[单位]: 列表[字符串] 请指教。谢谢你。

【问题讨论】:

  • 在 scala 中,您应该尝试从这些命令式概念(“运行循环”)中退后一步,并表达更高级别的意图。比如:val checkVal = obj.find(jf =&gt; jf.fieldName == "nameValue").map(_.value ==t).getOrElse(true)(我不知道具体的 API,但希望你明白)?
  • 对不起,如果这是愚蠢的问题。但我在这里假设 checkVal 是一个布尔值?你能解释一下.map(_.value ==t) 做了什么吗?谢谢。
  • 这是对Option 上的.map 的调用(find 的返回类型) - 理解这些内容的最简单方法是将其放入 IDE 并点击进入函数定义。如果选项存在,map 基本上将给定函数应用于选项中的值。 _.value==t 是一个匿名函数,它是一种简洁的书写方式,例如{jsonField =&gt; jsonField.value == t}

标签: scala


【解决方案1】:

你的一个问题是你在 yield 中有不同的返回类型:如果 t==name,返回类型是 break 的类型,如果 t!=name 返回类型是 Boolean。 在 scala 中,您没有 break 运算符,此行为是使用 breakable 构造和调用 break() 方法实现的,该方法实际上会引发异常以退出 breakable 块。您也可以在for 正文中使用if 语句来过滤您的结果:

import scala.util.control.Breaks._

breakable {
  for {
    JObject(obj) <- data
    JField("nameValue", JString(t)) <- obj
    if t == name
  } yield {
    checkVal = false
    break()
  }
}

更新: 我使用这种命令式方法是因为您是 scala 的新手,但这不是 scala 的方式。恕我直言,您应该坚持使用 cmets 中的 @Imm 代码来回答您的问题。

【讨论】:

    【解决方案2】:

    我实际上不喜欢在 for 循环中使用模式匹配,好像由于某种原因数据不是 JObject,它不会被很好地处理。我更喜欢下面的方法。

    data match {
      case JObject(fields) => fields.exists{
        case (name:String,value:JString) => name == "nameValue" && value.s == "name"
        case _ => false
      }
      case _ => false // handle error as not a JObject
    }
    

    编辑:修改为包含您的匹配项。

    【讨论】:

      【解决方案3】:

      我建议使用exists,因为它对所有集合成员都是惰性的。

      代码:-

      val list= Map(
              "nameValue1" -> 1,
              "nameValue2" -> 2,
              "nameValue3" -> 3,
              "nameValue4" -> 4,
              "nameValue5" -> 5
              )
      val requiredHeader = "nameValue2"
      var keyvalue:Int=0
      list.exists(p=>{ if(p._1.equalsIgnoreCase(requiredHeader))keyvalue=p._2;p._1.equalsIgnoreCase(requiredHeader) })
      
      if(keyvalue!=0){
              //header present
      }else{
              //header doesn't exit
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-04
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多