I want to combine two different length lists. For example;
val list1 = listOf(1,2,3,4,5)
val list2 = listOf("a","b","c")
I want to result like this
(1,"a",2,"b",3,"c",4,5)
Is there any suggestion?
You may use the .zip
function for that
list1.zip(list2){ a,b -> listOf(a,b)}.flatten()
The only problem is that it will only process elements, with both sets, so if (like in the example) let's have different size - it will not work
The alternative could be to add specific markers and filter them or to just use iterators for that. I found an elegant solution with sequence{..}
function
val result = sequence {
val first = list1.iterator()
val second = list2.iterator()
while (first.hasNext() && second.hasNext()) {
yield(first.next())
yield(second.next())
}
yieldAll(first)
yieldAll(second)
}.toList()
>>> list1 + list2
res12: kotlin.collections.List<kotlin.Any> = [1, 2, 3, 4, 5, a, b, c]
>>> list1.zip(list2).flatMap { listOf(it.first, it.second) } + list1.drop(list2.size)
res16: kotlin.collections.List<kotlin.Any> = [1, a, 2, b, 3, c, 4, 5]
You could do it like this:
val mergedList = with(setOf(list1, list2).sortedByDescending { it.count() }) {
first().mapIndexed { index, e ->
listOfNotNull(e, last().getOrNull(index))
}
}.flatten()
First, you put both lists in a Set
, then you sort it (descending) by the number of elements yielding a list of lists.
The first list has the most elements will be used for iteration.
Using mapIndexed
you can use the index
to access the corresponding element in the second list. If there is none, null
is returned and it will be filtered out by listOfNotNull
. In the end you flatten the resulting list of lists and you get the desired result:
[1, a, 2, b, 3, c, 4, 5]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With