[英]Scala functional programming concepts instead of multiple for loops
我正在嘗試在 Scala 中學習函數式編程。 現在我正在使用 OOP 方式讓 for 循環來完成工作。 我有兩個列表userCurrentRole
和entitlements
我做了雙重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 循環轉換為使用map
或filter
或兩者或任何 scala 的函數式編程特性的邏輯,但沒有for
循環?
編輯 1:在 double if.. 中添加了一個列表添加
好消息是:你已經在使用函數式風格了! 因為for
本身不是一個循環,而是一個“for comprehension”,它被分解為flatMap
和map
調用。 它只是更容易讀/寫。
但是,您應該避免的是可變變量,例如您在那里擁有的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 循環,但它們不是循環。 它們只是調用map
和flatMap
語法糖。 但是在您的情況下,對於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.