data class Person(val name: String, val age: String, val color: String)
val persons = listOf(Person("john", "20", "green"), Person("Mary", "20", "blue"))
val names = persons.map {it.name}
val ages = persons.map {it.age}
val colors = persons.map {it.color}
// I will need 3 iteration to get my names and ages and colors
val personsMap = persons.map { it.name to it.age }
val (names2, ages) = personsMap.unzip()
// I am using 1 iteration but with Map and uzip(), I can get names2,
// ages within a single iteration
// Now if I wish to get color
// By using map, or alternatives call helper.. can I retrieve names,
// ages and colors at one go
// I do know that we can use iteration forEachloop and add into a
// set/list, but
// are there better way of doing it
// val (names, ages, colors)
What are the alternative way to write to get multiple value in a single iteration to get its list from destructing.
CodePudding user response:
In order to collect lists of different properties, at least one iteration is required. this can be done by defining an extension function as
fun List<Person>.collectProperties(): Triple<List<String>, List<String>, List<String>>{
val (names, ages, colors) = listOf(mutableListOf<String>(), mutableListOf(), mutableListOf())
this.forEach { person ->
names.add(person.name)
ages.add(person.age)
colors.add(person.color)
}
return Triple(names, ages, colors)
}
now you can use this as
val persons = listOf(Person("john", "20", "green"), Person("Mary", "20", "blue"))
val(names, ages, colors) = persons.collectProperties()
CodePudding user response:
Your toList()
call is redundant, so you're iterating 3 times instead of twice.
I can't think of a way to do this with a single iteration using standard library higher-order functions. You could write a function like this that maps and unzips in one step so it only iterates once:
inline fun <T, U, V> Iterable<T>.doubleMap(transform: (T) -> Pair<U, V>): Pair<List<U>, List<V>> {
val size = if (this is Collection<*>) size else 10
val listU = ArrayList<U>(size)
val listV = ArrayList<V>(size)
for (t in this) {
with (transform(t)) {
listU = first
listV = second
}
}
return listU to listV
}