github.1485827954.workers.dev/nektos/act@v0.2.63/pkg/common/cartesian.go (about) 1 package common 2 3 // CartesianProduct takes map of lists and returns list of unique tuples 4 func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interface{} { 5 listNames := make([]string, 0) 6 lists := make([][]interface{}, 0) 7 for k, v := range mapOfLists { 8 listNames = append(listNames, k) 9 lists = append(lists, v) 10 } 11 12 listCart := cartN(lists...) 13 14 rtn := make([]map[string]interface{}, 0) 15 for _, list := range listCart { 16 vMap := make(map[string]interface{}) 17 for i, v := range list { 18 vMap[listNames[i]] = v 19 } 20 rtn = append(rtn, vMap) 21 } 22 return rtn 23 } 24 25 func cartN(a ...[]interface{}) [][]interface{} { 26 c := 1 27 for _, a := range a { 28 c *= len(a) 29 } 30 if c == 0 || len(a) == 0 { 31 return nil 32 } 33 p := make([][]interface{}, c) 34 b := make([]interface{}, c*len(a)) 35 n := make([]int, len(a)) 36 s := 0 37 for i := range p { 38 e := s + len(a) 39 pi := b[s:e] 40 p[i] = pi 41 s = e 42 for j, n := range n { 43 pi[j] = a[j][n] 44 } 45 for j := len(n) - 1; j >= 0; j-- { 46 n[j]++ 47 if n[j] < len(a[j]) { 48 break 49 } 50 n[j] = 0 51 } 52 } 53 return p 54 }