在 Go 中实现 Ruby 风格的笛卡尔积
Implement Ruby style Cartesian product in Go
我想得到 a
, b
, c
, d
:
的笛卡尔积
a = ['a1']
b = ['b1', 'b2']
c = ['c1', 'c2', 'c3']
d = ['d1']
这是 Ruby 中的代码:
e = [b, c, d]
print a.product(*e)
输出为:
[
["a1", "b1", "c1", "d1"],
["a1", "b1", "c2", "d1"],
["a1", "b1", "c3", "d1"],
["a1", "b2", "c1", "d1"],
["a1", "b2", "c2", "d1"],
["a1", "b2", "c3", "d1"]
]
有没有类似的包或者函数可以在Golang中做product?
这只是简化版本,实际上,输入数据如 [['a1']、['b1'、'b2']、['c1'、'c2'、 'c3],['d1'],['e1',...],...].
如果您需要一组编译时未知的嵌套索引循环,您可以使用这样的代码。
package main
import "fmt"
// NextIndex sets ix to the lexicographically next value,
// such that for each i>0, 0 <= ix[i] < lens(i).
func NextIndex(ix []int, lens func(i int) int) {
for j := len(ix) - 1; j >= 0; j-- {
ix[j]++
if j == 0 || ix[j] < lens(j) {
return
}
ix[j] = 0
}
}
func main() {
e := [][]string{
{"a1"},
{"b1", "b2"},
{"c1", "c2", "c3"},
{"d1"},
}
lens := func(i int) int { return len(e[i]) }
for ix := make([]int, len(e)); ix[0] < lens(0); NextIndex(ix, lens) {
var r []string
for j, k := range ix {
r = append(r, e[j][k])
}
fmt.Println(r)
}
}
输出为:
[a1 b1 c1 d1]
[a1 b1 c2 d1]
[a1 b1 c3 d1]
[a1 b2 c1 d1]
[a1 b2 c2 d1]
[a1 b2 c3 d1]
我想得到 a
, b
, c
, d
:
a = ['a1']
b = ['b1', 'b2']
c = ['c1', 'c2', 'c3']
d = ['d1']
这是 Ruby 中的代码:
e = [b, c, d]
print a.product(*e)
输出为:
[
["a1", "b1", "c1", "d1"],
["a1", "b1", "c2", "d1"],
["a1", "b1", "c3", "d1"],
["a1", "b2", "c1", "d1"],
["a1", "b2", "c2", "d1"],
["a1", "b2", "c3", "d1"]
]
有没有类似的包或者函数可以在Golang中做product? 这只是简化版本,实际上,输入数据如 [['a1']、['b1'、'b2']、['c1'、'c2'、 'c3],['d1'],['e1',...],...].
如果您需要一组编译时未知的嵌套索引循环,您可以使用这样的代码。
package main
import "fmt"
// NextIndex sets ix to the lexicographically next value,
// such that for each i>0, 0 <= ix[i] < lens(i).
func NextIndex(ix []int, lens func(i int) int) {
for j := len(ix) - 1; j >= 0; j-- {
ix[j]++
if j == 0 || ix[j] < lens(j) {
return
}
ix[j] = 0
}
}
func main() {
e := [][]string{
{"a1"},
{"b1", "b2"},
{"c1", "c2", "c3"},
{"d1"},
}
lens := func(i int) int { return len(e[i]) }
for ix := make([]int, len(e)); ix[0] < lens(0); NextIndex(ix, lens) {
var r []string
for j, k := range ix {
r = append(r, e[j][k])
}
fmt.Println(r)
}
}
输出为:
[a1 b1 c1 d1]
[a1 b1 c2 d1]
[a1 b1 c3 d1]
[a1 b2 c1 d1]
[a1 b2 c2 d1]
[a1 b2 c3 d1]