如何用Ruby从数组/哈希生成所有可能的字符串组合?
Ruby生成所有字符串组合的可扩展方案
核心思路
通过笛卡尔积获取所有数组元素的组合,结合哈希关联数据源与格式化占位符,实现可扩展的字符串生成逻辑——后续新增数据源仅需添加键值对,无需修改核心代码。
基础实现(对应初始需求)
# 数据源:键名需与格式化字符串的占位符完全匹配 data = { person: ["Andy", "Budi", "Charles"], vehicle: ["Bicycle", "Car", "Bajaj"], destination: ["USA", "Bali", "Paradise"] } # 格式化模板 string_format = "%{person} ride %{vehicle} to %{destination}" # 生成所有元素的笛卡尔积 combinations = data.values.inject(&:product).map(&:flatten) # 输出带编号的结果 combinations.each_with_index do |values, idx| # 将组合元素与键名配对成哈希,填充模板 puts "#{idx + 1}. #{string_format % data.keys.zip(values).to_h}" end
运行后会生成27条符合预期的结果,每条对应一组person-vehicle-destination的组合。
扩展场景(新增数据源)
如果后续需要添加adjectives等新数组,只需在data哈希中新增键值对,同时调整格式化模板即可,核心逻辑完全不变:
# 新增数据源后的配置 data = { person: ["Andy", "Budi", "Charles"], vehicle: ["Bicycle", "Car", "Bajaj"], destination: ["USA", "Bali", "Paradise"], adjectives: ["happily", "sadly"], his_or_her: ["his", "her"] } # 新的格式化模板 string_format = "%{destination} has been visited by %{person} using %{his_or_her} %{vehicle} %{adjectives}" # 核心逻辑无变化 combinations = data.values.inject(&:product).map(&:flatten) combinations.each_with_index do |values, idx| puts "#{idx + 1}. #{string_format % data.keys.zip(values).to_h}" end
关键说明
- 笛卡尔积生成:
data.values.inject(&:product)会自动计算所有数组的笛卡尔积,支持任意数量的输入数组; - 动态占位符填充:
data.keys.zip(values).to_h将组合元素与对应的占位符键名绑定,无需手动逐个匹配; - 扩展性保障:新增数据源仅需在
data中添加键值对,修改格式化模板即可,核心生成逻辑无需调整。
内容的提问来源于stack exchange,提问作者Kevin Tanudjaja
相关产品推荐
相关产品推荐

