I have an extension function for an interface that will replace a single argument in the path and return a new anonymous implementation of that interface. When applying this pattern for multiple arguments, though, I've only been able to get it to work by iterating over the map of arguments and values and assigning the result to a var
.
The reassignment of a var
in this implementation doesn't feel like it's the "right" approach, though. Is there a more idiomatic way to accomplish the same goal?
interface NavRoute {
val path: String
val title: Int
}
fun NavRoute.withArgument(argument: String, value: Any) : NavRoute {
val newPath = this.path.replace("{$argument}", value.toString())
val thisTitle = this.title
return object : NavRoute {
override val path: String = newPath
override val title: Int = thisTitle
}
}
fun NavRoute.withArguments(arguments: Map<String, Any>) : NavRoute {
var newRoute = this
arguments.map {
newRoute = newRoute.withArgument(it.key, it.value)
}
return newRoute
}
I attempted to rewrite this using a recursive approach, but I couldn't ever get anything to compile.
You can avoid var
by first converting the arguments Map
to an Iterable
and then folding on that:
fun NavRoute.withArguments(arguments: Map<String, Any>): NavRoute =
arguments.entries.fold(this) { route, entry -> route.withArgument(entry.key, entry.value) }
Your version is more readable though.
BTW, you have "{$argument}"
, is that really what you want?