簡體   English   中英

Scala 函數式編程概念而不是多個 for 循環

[英]Scala functional programming concepts instead of multiple for loops

我正在嘗試在 Scala 中學習函數式編程。 現在我正在使用 OOP 方式讓 for 循環來完成工作。 我有兩個列表userCurrentRoleentitlements我做了雙重for循環在其中:

for {
    curr <- userCurrentRole {
    ent <- entitlements
} {
        if (ent.userEmail.split("@")(0) == curr.head) {
            if (ent.roleName != curr(1)) {
                grantOrRevoke += 1
                grantList += SomeCaseClass(curr.head, ent.roleName)
            }
        }
    }
}

是否可以將這個雙 for 循環轉換為使用mapfilter或兩者或任何 scala 的函數式編程特性的邏輯,但沒有for循環?

編輯 1:在 double if.. 中添加了一個列表添加

好消息是:你已經在使用函數式風格了! 因為for本身不是一個循環,而是一個“for comprehension”,它被分解為flatMapmap調用。 它只是更容易讀/寫。

但是,您應該避免的是可變變量,例如您在那里擁有的grantOrRevoke

val revocations = for {
    curr <- userCurrentRole {
    ent <- entitlements
    if ent.userEmail.split("@")(0) == curr.head
    if ent.roleName != curr(1)
} yield {
  1
}

revocations.size // same as revocations.sum

請注意, for 塊中的if s(通常)對withFilter調用進行脫糖,這通常比filter調用更可取,因為后者建立了一個新集合,而前者避免了這種情況。

你可以這樣寫:

val grantOrRevoke = userCurrentRole
    .map(curr => entitlements
        .filter(ent => ent.userEmail.split("@")(0) == curr.head && ent.roleName != curr(1))
        .size)
    .sum

好吧,您已經在使用一些高階函數,只是您沒有注意到它,因為您認為它們是 for 循環,但它們不是循環。 它們只是調用mapflatMap語法糖。 但是在您的情況下,對於foreach和可變性,想要並不能使其發揮作用。

我建議你看看scaladoc ,你會發現集合有很多有用的方法。 例如,在這種情況下,我們可以使用count & sum

val grantOrRevoke = userCurrentRole.iterator.map {
  // Maybe it would be better to have a list of tuples instead of a list of lists.
  case List(username, userRole) =>
    entitlements.count { ent =>
      (ent.userEmail.split("@", 2)(0) == username) && (ent.roleName == userRole)
    }
}.sum

暫無
暫無

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

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