Go:迭代n个任意切片中元素的所有可能组合

问题描述 投票:0回答:1

假设我们有一个具有

n
可见字段的结构,这些字段是任意类型和长度的切片:

var parameters := struct {
   Parameters1 []int
   Parameters2 []byte
   // ...
   ParametersN [][]byte
} {
   []int{1,2,4},
   []byte{0,1,2,3},
   //...
   [][]byte{[]byte("hi"), []byte("goodbye")}
}

我们如何迭代它以获得所有可能的组合?比如:

for combination in generateAllCombinations(parameters) {
   fmt.println(combination.Parameter1, combination.Parameter2, ..., combination.ParameterN)
}
//> 1, 0, ..., hi
//> 2, 0, ..., hi
//> 4, 0, ..., hi
//> 1, 1, ..., hi
//> ...

理想情况下,它不应该预先计算所有组合,而是迭代它们。

go combinations slice combinatorics
1个回答
0
投票
import (
    "fmt"
    "reflect"
)

type Parameters struct {
    Parameters1 []int
    Parameters2 []byte
    Parameters3 []string
    // so on
}

func unpackArray(s any) []any {
    v := reflect.ValueOf(s)
    r := make([]any, v.Len())
    for i := 0; i < v.Len(); i++ {
        r[i] = v.Index(i).Interface()
    }
    return r
}

func (t Parameters) generateAllCombinations() {
    parameters := [][]any{}

    values := reflect.ValueOf(t)

    for i := 0; i < values.NumField(); i++ {
        value := values.Field(i).Interface()
        parameters = append(parameters, unpackArray(value))
    }

    generateCombinations(parameters, []interface{}{}, 0)
}

func generateCombinations(arrays [][]interface{}, prefix []interface{}, index int) {
    if index == len(arrays) {
        fmt.Println(prefix...)
        return
    }

    for _, element := range arrays[index] {
        generateCombinations(arrays, append(prefix, element), index+1)
    }
}

因此,在这段代码中,它首先使用reflect.ValueOf为struct中的所有字段创建一个any类型的二维数组,以获取struct字段的所有值(您应该知道所有字段必须是数组;否则,需要进行类型检查)然后使用 unpackArray 函数,如果打印参数的所有组合,它可以使用简单的递归方法将任何类型转换为任何类型的数组。

© www.soinside.com 2019 - 2024. All rights reserved.