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  }