I have such kotlin code. I didn't write it very elegantly, but it works correctly. How can I write this more beautifully using kotlin tools?
I need to apply all elements from the filters
list to the query
object.
fun create(filters: List<FilterFactory.Filter>, searchQuery: SearchQuery): Query {
var query = Query()
filters.forEach { filter -> query = filter.apply(query) }
return query
}
CodePudding user response:
You can refactor the implementation of the function by using fold here:
fun create(filters: List<FilterFactory.Filter>): Query =
filters.fold(Query()) { q, f -> f.apply(q) }
Note that your initial code didn't make use of the searchQuery
parameter, so I removed it.
As for the API, you might want to use an extension function instead, with the toX()
convention for the name. For instance:
fun List<FilterFactory.Filter>.toQuery(): Query =
fold(Query()) { q, f -> f.apply(q) }
toQuery()
on a list of filters might be confusing to some, though. Maybe a better approach would be an extension on Query
itself:
fun Query.withFilters(filters: List<FilterFactory.Filter>): Query =
filters.fold(this) { q, f -> f.apply(q) }
Then to use it you'll need to provide the initial Query
instance on the call site:
val filteredQuery = Query().withFilters(filters)
CodePudding user response:
Another thing you could do is a simple apply
call to configure the object you've created:
fun create(filters: List<FilterFactory.Filter>, searchQuery: SearchQuery): Query {
return Query().apply {
filters.forEach { filter -> filter.apply(this) }
}
}
which lends itself nicely to the single-expression style
fun create(filters: List<FilterFactory.Filter>, searchQuery: SearchQuery) =
Query().apply {
filters.forEach { filter -> filter.apply(this) }
}
(I'm assuming you're using searchQuery
in there somewhere, e.g. the Query
constructor)