实现 Go 语言中的 Ruby 风格笛卡尔积运算
发布时间 - 2026-01-28 00:00:00 点击率:次本文介绍如何在 go 中高效实现任意数量字符串切片的笛卡尔积(cartesian product),支持动态长度输入,无需编译期确定维度,精准复现 ruby 的 `array#product` 行为。
Go 标准库未内置笛卡尔积函数,但可通过索引迭代法优雅实现——其核心思想是将多维遍历抽象为「字典序递增的索引数组」,类似多进制计数器。以下是一个通用、内存友好且无依赖的实现:
package main
import "fmt"
// NextIndex 将索引数组 ix 更新为字典序下一个有效状态:
// 每个 ix[i] 满足 0 ≤ ix[i] < lens(i),lens(i) 表示第 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 // 归零并继续向高位进位
}
}
// CartesianProduct 计算任意数量字符串切片的笛卡尔积,返回 [][]string
func CartesianProduct(sets [][]string) [][]string {
if len(sets) == 0 {
return [][]string{{}}
}
for _, s := range sets {
if len(s) == 0 {
return [][]string{} // 任一集合为空 → 结果为空
}
}
lens := func(i int) int { return len(sets[i]) }
result := make([][]string, 0)
ix := make([]int, len(sets))
// 主循环:从全0索引开始,直到第一维越界
for ix[0] < lens(0) {
// 构造当前组合
combo := make([]string, len(sets))
for j, k := range ix {
combo[j] = sets[j][k]
}
result = append(result, combo)
// 生成下一组索引
NextIndex(ix, lens)

}
return result
}
func main() {
a := []string{"a1"}
b := []string{"b1", "b2"}
c := []string{"c1", "c2", "c3"}
d := []string{"d1"}
// 等价于 Ruby 的 a.product(*e),其中 e = [b, c, d]
sets := [][]string{a, b, c, d}
result := CartesianProduct(sets)
for _, r := range result {
fmt.Println(r)
}
}✅ 关键特性说明:
- 动态维度支持:sets 是 [][]string 类型,长度可在运行时任意变化;
- 边界健壮性:自动处理空集合(返回空结果)和单元素集合;
- 零分配优化:NextIndex 复用同一索引数组,避免频繁内存分配;
- 可扩展性强:只需修改 lens 函数和组合构造逻辑,即可适配任意类型(如 [][]int)。
⚠️ 注意事项:
- 笛卡尔积结果大小为各集合长度乘积(∏|set_i|),对大数据集需警惕内存爆炸;建议流式处理(如传入回调函数替代构建完整 [][]string);
- 若需兼容 nil 切片,应在 CartesianProduct 开头增加 if sets == nil 判断;
- Ruby 的 product 支持链式调用与块参数(如 a.product(b) { |x,y| ... }),Go 中可封装为带 func([]string) 参数的版本以实现类似流式消费。
该方案不依赖第三方包,符合 Go 的简洁哲学,是生产环境中实现笛卡尔积的推荐实践。
# go
# 大数据
# app
# 回调函数
# ai
# 标准库
# ruby
# golang
# String
# Array
# if
# 封装
# 字符串
# int
# 切片
# nil
# 笛卡尔
# 链式
# 多维
# 为空
# 是一个
# 流式
# 遍历
# 只需
# 可在
# 应在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明
Laravel如何实现本地化和多语言支持?(i18n教程)
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
油猴 教程,油猴搜脚本为什么会网页无法显示?
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
常州企业网站制作公司,全国继续教育网怎么登录?
怎样使用JSON进行数据交换_它有什么限制
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
手机软键盘弹出时影响布局的解决方法
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Android使用GridView实现日历的简单功能
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
使用C语言编写圣诞表白程序
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
在线制作视频网站免费,都有哪些好的动漫网站?
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
jQuery中的100个技巧汇总
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
如何破解联通资金短缺导致的基站建设难题?
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
如何快速查询域名建站关键信息?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
微信小程序 require机制详解及实例代码
使用spring连接及操作mongodb3.0实例
网站建设整体流程解析,建站其实很容易!
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
高端建站三要素:定制模板、企业官网与响应式设计优化
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
JS弹性运动实现方法分析
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
如何构建满足综合性能需求的优质建站方案?
深圳网站制作的公司有哪些,dido官方网站?
如何在建站之星网店版论坛获取技术支持?
Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布
如何获取上海专业网站定制建站电话?
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
活动邀请函制作网站有哪些,活动邀请函文案?
如何快速完成中国万网建站详细流程?
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
java ZXing生成二维码及条码实例分享
如何用搬瓦工VPS快速搭建个人网站?
如何获取PHP WAP自助建站系统源码?
Laravel如何生成API文档?(Swagger/OpenAPI教程)
如何快速登录WAP自助建站平台?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?


