Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform action for all combinations of elements in lists?

Tags:

kotlin

I have multiple lists, for the sake of simplicity, let's say 2:

val names = listOf("John", "Tom")
val days = listOf(1, 2, 3)

And I want to iterate over all the combinations of these possible values with a function f: (String, Int): Unit:

f("John", 1)
f("John", 2)
f("John", 3)
f("Tom", 1)
f("Tom", 2)
f("Tom", 3)

I'd like to find out the idiomatic way to do this in kotlin. Off the top of my head, I imagine that this can be done with a nested map. Something along the lines of:

a.map { itA -> 
  b.map { itB ->
    f(itA, itB)
  }
}

EDIT: This doesn't seem to work for me though as it returns:

[() -> kotlin.collections.List<kotlin.Unit>, () -> kotlin.collections.List<kotlin.Unit>]
like image 278
breezymri Avatar asked Oct 23 '17 17:10

breezymri


People also ask

How do you generate all possible combinations of two lists?

Once the queries from the tables are ready, go to Data > Get Data > Combine Queries > Merge to open the Merge dialog of Power Query. Select each table in the drop downs. Click on the column for each table to select them. Finally select Full Outer option for Join Kind to join by all rows from both tables.

How do you generate all possible combinations of two lists in Python?

The unique combination of two lists in Python can be formed by pairing each element of the first list with the elements of the second list. Method 1 : Using permutation() of itertools package and zip() function. Approach : Import itertools package and initialize list_1 and list_2.


1 Answers

The name of the output you're looking for is a Cartesian Product.

If you don't need all of the combinations up front, and you're just searching for one or more, you could make it a lazily generated sequence:

private fun <A, B> lazyCartesianProduct(
    listA: Iterable<A>,
    listB: Iterable<B>
): Sequence<Pair<A, B>> =
    sequence {
        listA.forEach { a ->
            listB.forEach { b ->
                yield(a to b)
            }
        }
    }

Then you can map, filter etc only what you need:

val names = listOf("John", "Tom")
val days = listOf(1, 2, 3)

lazyCartesianProduct(names, days)
    .map { it.toSomethingElse() }
    .find { it.isWhatImLookingFor() }
like image 97
Tom Hanley Avatar answered Nov 08 '22 20:11

Tom Hanley