Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine two different length lists in kotlin?

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?

like image 392
Bahadır Bulduk Avatar asked Mar 28 '19 18:03

Bahadır Bulduk


3 Answers

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()
like image 109
Eugene Petrenko Avatar answered Sep 22 '22 01:09

Eugene Petrenko


  1. If the elements from the source lists can occur in any order in the resulting list, then
>>> list1 + list2
res12: kotlin.collections.List<kotlin.Any> = [1, 2, 3, 4, 5, a, b, c]
  1. If the elements from the source lists should alternate in the resulting list and list1 is longer than list2, then
>>> 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]
like image 26
Venkatesh-Prasad Ranganath Avatar answered Sep 20 '22 01:09

Venkatesh-Prasad Ranganath


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]

like image 41
Willi Mentzel Avatar answered Sep 19 '22 01:09

Willi Mentzel