2015-04-22 124 views
0

我想知道如何改進這個代碼,使其更具可讀性和流暢性。感謝您的幫助,謝謝。我該如何改進用Scala編寫的這段代碼?

// filter DWT based on Zone 
val dwtListZon = query.zoneOpt match { 
    case None => dwtListStn 
    case Some(zon) => { 
    if (zon.crwStn333 == "all") { 
     dwtListStn 
    } 
    dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3) 
    } 
} 

我只是想了解如何代碼應該寫的,在簡單性和可讀性方面,更聲明(如果可能)的方式。

下面的答案顯示了不同的風格做同樣的事情,這也有助於擴大我一般在FP和斯卡拉的見解。感謝那!

+5

也許對於codereview.stackexchange – smk

+0

我投票作爲題外話,因爲問題屬於codereview.stackexchange.com關閉這個問題一個問題 –

+0

這不會是對話題的代碼在沒有額外的上下文的情況下進行回顧,瞭解該代碼應該實現什麼以及在什麼情況下。 – Phrancis

回答

2
val dwtListZon = query.zoneOpt filter (_.crwStn333 != "all") map (zon => 
dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3)) getOrElse dwtListStn 

,或者如果你想可讀性

val filteredSomething = for(zon <- query.zoneOpt if zon.crwStn333 != "all") 
    yield dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3) 
val dwtListZon = filteredSomething getOrElse dwtListStn 
+0

這就是我一直在尋找的,謝謝! –

+0

@AS_其實我犯了小錯誤,檢查更新 – Odomontois

+0

來自OOP背景我試圖學習更多功能的編碼方式,並且看到做同樣事情的不同方式真的有幫助!感謝您花時間分享另一種編碼風格。我很感激,真的。 –

5

您也可以考慮fold功能,您可在Option。它往往是與Options默認值的很好的語法,你會得到使用優雅的部分功能語法:

query.zoneOpt.fold(dwtListStn) { 
    case zon if zon.crwStn333 == "all" => dwtListStn 
    case zon => dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3) 
} 

這裏的另一個普遍的策略是圍繞翻轉操作。邏輯的所有分支返回dwtListStn一些過濾或未經過濾的版本,所以你可以爲filter受孕整個操作過程:

dwtListStn.filter { dwt => 
    query.zoneOpt match { 
     case Some(zone) if zone.crwStn333 == "all" => false 
     case Some(zone) => dwt.crwStnAbbr3 == zon.crwStnAbbr3 
     case None => false 
    } 
} 
+0

感謝您的答案! –

1

普通的比賽可以清楚的了。只是反向如果條件:

query.zoneOpt match { 
    case Some(zon) if (zon.crwStn333 != "all") => 
     dwtListStn.filter(_.crwStnAbbr3 == zon.crwStnAbbr3) 
    case _ => 
     dwtListStn 
}