matrix is done

Signed-off-by: Casey Lee <cplee@nektos.com>
This commit is contained in:
Casey Lee
2020-02-17 10:11:16 -08:00
parent 5b7019cd0b
commit f8fb88816a
8 changed files with 219 additions and 46 deletions

54
pkg/common/cartesian.go Normal file
View File

@@ -0,0 +1,54 @@
package common
// CartesianProduct takes map of lists and returns list of unique tuples
func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interface{} {
listNames := make([]string, 0)
lists := make([][]interface{}, 0)
for k, v := range mapOfLists {
listNames = append(listNames, k)
lists = append(lists, v)
}
listCart := cartN(lists...)
rtn := make([]map[string]interface{}, 0)
for _, list := range listCart {
vMap := make(map[string]interface{})
for i, v := range list {
vMap[listNames[i]] = v
}
rtn = append(rtn, vMap)
}
return rtn
}
func cartN(a ...[]interface{}) [][]interface{} {
c := 1
for _, a := range a {
c *= len(a)
}
if c == 0 {
return nil
}
p := make([][]interface{}, c)
b := make([]interface{}, c*len(a))
n := make([]int, len(a))
s := 0
for i := range p {
e := s + len(a)
pi := b[s:e]
p[i] = pi
s = e
for j, n := range n {
pi[j] = a[j][n]
}
for j := len(n) - 1; j >= 0; j-- {
n[j]++
if n[j] < len(a[j]) {
break
}
n[j] = 0
}
}
return p
}

View File

@@ -0,0 +1,28 @@
package common
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCartisianProduct(t *testing.T) {
assert := assert.New(t)
input := map[string][]interface{}{
"foo": []interface{}{1, 2, 3, 4},
"bar": []interface{}{"a", "b", "c"},
"baz": []interface{}{false, true},
}
output := CartesianProduct(input)
assert.Len(output, 24)
for _, v := range output {
assert.Len(v, 3)
assert.Contains(v, "foo")
assert.Contains(v, "bar")
assert.Contains(v, "baz")
}
}