Idiomatic way to create n-ary cartesian product (combinations of several sets of parameters)

后端 未结 5 1147
执笔经年
执笔经年 2020-12-20 18:56

To create all possible combinations of two sets of parameters and perform an action on them, you can do:

setOf(foo, bar, baz).forEach { a ->
    setOf(0,          


        
5条回答
  •  半阙折子戏
    2020-12-20 19:21

    Here's another way to do it with an arbitrary combiner function:

    fun  product(xs: Collection, ys: Collection, combiner: (T, U) -> V): Collection =
        xs.flatMap { x ->
            ys.map { y ->
                combiner(x, y)
            }
        }
    
    operator fun  Set.times(ys: Set): Set> =
        product(this, ys) { x, y ->
            if (x is Set<*>) x + y // keeps the result flat
            else setOf(x, y)
        }.toSet()
    
    operator fun  List.times(ys: List): List> =
        product(this, ys) { x, y ->
            if (x is List<*>) x + y // keeps the result flat
            else listOf(x, y)
        }.toList()
    
    // then you can do
    
    listOf(1, 2, 3) * listOf(true, false)
    
    // or
    
    setOf(1, 2, 3) * setOf(true, false)
    
    // you can also use product's combiner to create arbitrary result objects, e.g. data classes
    
    

提交回复
热议问题