我不得不把它分解對部分和部分進行分類,從而制定出更小的方法。 它在我簡單的實驗中工作,並擺脫它可以重複的地方,但可能不是可讀的?
請注意,除非您進行反思,否則您仍需要創建參數的名稱以及如何過濾它。
這看起來是一樣tuxdna的答案除了與類型,以增加可讀性和可維護性
SETUP
case class Request(params: Map[String, String])
case class Result(category: String, source: String)
type Filterer = (Result, String) => Boolean
case class FilterInfo(paramName: String, filterer: Filterer)
type Analyzer = FilterInfo => List[Result]
val request = Request(Map("source"->"b"))
提取方法
def reduce(filterInfos: List[FilterInfo], results: List[Result]) = {
filterInfos.foldLeft(results) { (currentResult, filterInfo) =>
request.params.get(filterInfo.paramName)
.map(filterVal => currentResult.filter(filterInfo.filterer(_, filterVal)))
.getOrElse(currentResult)
}
}
用法
val filterInfos = List(
FilterInfo("source", (result, filterVal) => result.source == filterVal),
FilterInfo("category", (result, filterVal) => result.category == filterVal))
val res = List(Result("a","a"), Result("b", "b"))
reduce(filterInfos, res)
用在你的例子會比較像這樣:
get("/MostClicked") { request =>
val res = MongoDbOps.findMostClicked()
val filterInfos = List(
FilterInfo("source", (result, filterVal) => result.source == filterVal),
FilterInfo("category", (result, filterVal) => result.category == filterVal))
val finalResult = reduce(filterInfos, res)
render.plain {
finalResult.toJson.prettyPrint
}.toFuture
}
什麼是'res1'點?你可能想在res2中指定'res1.filter'? – 2014-09-28 17:13:35
@EndeNeu你是對的,修正了 – Zavior 2014-09-28 17:22:12
既然你想對同一個數據應用兩個過濾器,你可以先組合這兩個過濾器。因此,在第二場比賽中你不會有'res1',但是'res',這使得兩個代碼片段更加相似。我仍然不知道如何擺脫'.source'和'.category'的區別。我只是在想:「如果兩場比賽是相同的,你可以提取它們」 – 2014-09-28 17:39:00