簡體   English   中英

Scala:如何以功能方式更改此代碼?

[英]Scala: how to change this code in functional way?

我有這個列表例如:

val list = List(
    Map("a" -> "John", "b" -> 20, "c" -> true), 
    Map("a" -> "Derp", "b" -> 10, "c" -> false), 
    Map("b" -> 8, "c" -> true),
    Map("a" -> "asdf", "b" -> 50, "c" -> true)
)

我有這個代碼處理上面的列表,我想以最有效的方式將其更改為功能樣式:

var result = ""
breakable {
    for (m <- list) {
        if (m.get("a").isEmpty) {
            result = "Error A"
            break()
        }
        if (m.get("b").isEmpty) {
            result = "Error B"
            break()
        }
    }
}

在上面的代碼中,如果“a”不存在,則if檢查僅在退出循環之前進行一次。 如果“b”不存在,則檢查完成兩次。

我嘗試將其更改為功能代碼:

val result = (for { 
    m <- list
    a = m.get("a").isEmpty
    b = m.get("b").isEmpty
    if a || b
} yield {
    if (a) 
        "Error A"
    else
        "Error B"
}).headOption.getOrElse("")

看起來好像“a”不存在,如果檢查將進行兩次,如果“b”不存在,則將完成三次。

還有.headOption.getOrElse("")開銷。 如果我能直接得到字符串結果會很好。

誰能提供更好的解決方案?

list.view
    .map(m => if (m.get("a").isEmpty) "Error A" 
              else if (m.get("b").isEmpty) "Error B"
              else "")
    .find(_.nonEmpty)
    .getOrElse("")

請注意視圖使其不嚴格,以便在第一個失敗元素后停止。

使用if語句作為部分函數略微更整潔,如果地圖中既沒有“a”或“b”也未定義,並且使用包含

list.collectFirst{case m if !(m contains "a") => "Error A"
                  case m if !(m contains "b") => "Error B"}
    .getOrElse("")

有索引

list.view
    .zipWithIndex
    .map{case (m,i) => if (m.get("a").isEmpty) "Error A:"+ i
                       else if (m.get("b").isEmpty) "Error B:" + i
                       else ""}
    .find(_.nonEmpty)
    .getOrElse("")
    //> res1: String = Error A:2

並使用collectFirst

list.zipWithIndex
    .collectFirst{case (m, i) if !(m contains "a") => "Error A:" + i
                  case (m, i) if !(m contains "b") => "Error B:" + i}
    .getOrElse("")

僅作為附錄,另一個可行的解決方案是使用遞歸:

def getError(list: List[Map[String, Any]]): String = {
    if (list.nonEmpty) {
        val m = list.head
        if (m.get("a").isEmpty) 
            "Error A"
        else if (m.get("b").isEmpty)
            "Error B"
        else
            getError(list.tail)
    } else ""
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM