如何生成所有可能的组合

时间:2015-11-18 20:17:29

标签: ruby recursion combinations

我有一个像这样的字符串数组:

[
  "productRankingOct12:LessPopularityEPC",
  "productRankingOct12:CtrEpcJob", 
  "productRankingOct12:DeviceSpecificLPE", 
  "guidedSearch:false", 
  "guidedSearch:true", 
  "spotfront4:true", 
  "spotfront4:false",
  "postClick4:ipsa", 
  "postClick4:false",
  "trendingModule:false"
]

我必须根据给定的键:值对构建URL。我想要元素的组合:

[
  "productRankingOct12:LessPopularityEPC",
  "productRankingOct12:CtrEpcJob", 
  "productRankingOct12:DeviceSpecificLPE",
  "guidedSearch:false", 
  "guidedSearch:true", 
  "productRankingOct12:LessPopularityEPC & guidedSearch:false"
  "productRankingOct12:CtrEpcJob & guidedSearch:false"
  "productRankingOct12:DeviceSpecificLPE & guidedSearch:false"
  "productRankingOct12:LessPopularityEPC & guidedSearch:true"
  "productRankingOct12:CtrEpcJob & guidedSearch:true"
  "productRankingOct12:DeviceSpecificLPE & guidedSearch:true"
  "productRankingOct12:LessPopularityEPC & guidedSearch:false & spotfront4:true"
  "productRankingOct12:CtrEpcJob & guidedSearch:false & "spotfront4:true""
  "productRankingOct12:DeviceSpecificLPE & guidedSearch:false & "spotfront4:true""
  "productRankingOct12:LessPopularityEPC & guidedSearch:true & "spotfront4:true""
]

我试图用这个来生成排列:

def Automate_AB_tests.permutation(arg_keyVal)
  return [arg_keyVal] if arg_keyVal.size < 2
  ch = arg_keyVal[0] 
  permutation(arg_keyVal[1..-1]).each_with_object([]) do |perm,result|
    (0..perm.size).each {|i| result << perm.dup.insert(i,ch)}
  end
end

但似乎它正在采取所有元素,并且它崩溃了。我不想置换所有元素。我想要如上所述的所需输出。请任何人都可以帮助我。

1 个答案:

答案 0 :(得分:0)

首先,我不能&#39;找出你的输出中"trendingModule:false"到处都缺失的原因。

为什么输出中缺少行"spotfront4:true""spotfront4:false""postClick4:ipsa""postClick4:ipsa"等?包含或排除每种组合背后的逻辑是什么?

当然,由于重复的密钥,您希望排除"key:true&key:false"之类的行。

其次,这个程序产生了所有可能的组合,但这不是你想要的,对吧? 215个元素,比你在例子中列出的更多

opts = [
  "productRankingOct12:LessPopularityEPC",
  "productRankingOct12:CtrEpcJob", 
  "productRankingOct12:DeviceSpecificLPE", 
  "guidedSearch:false", 
  "guidedSearch:true", 
  "spotfront4:true", 
  "spotfront4:false",
  "postClick4:ipsa", 
  "postClick4:false",
  "trendingModule:false"
]

normal_opts = Hash.new
opts.each do |e|
  k, v = e.split(":")
  (normal_opts[k] ||= []) << v
end

# normal_ops looks like this
#normal_opts = {
#  "productRankingOct12" => ["LessPopularityEPC", "CtrEpcJob", "DeviceSpecificLPE"],
#  "guidedSearch" => ["false", "true"],
#  "spotfornt4" => ["true", "false"],
#  "postClick4" => ["ipsa", "false"],
#  "trendingModule" => ["false"]
#}

# nobody is ever going to mantain this
result = normal_opts.keys.length.times.map do |i|
  normal_opts.keys.combination(i + 1).map do |keys|
    combs = keys.map { |k|
      normal_opts[k].map { |e|
        "#{k}:#{e}"
      }
    }
    # good luck understanding this!
    combs.first.product(*combs[1..-1]).map{|e| e.join("&")}
  end
end

puts result.flatten

如果你更好地解释自己,我可以改进我的答案