我必须将n个数组相乘。
示例:
我创建了一个算法来做到这一点,效果很好。
# input
entries = ["$var1$", "$var2$", "$var3$"]
data = [["a", "b", "c"], ["1", "2"], ["&", "(", "$"]]
num_combinaison = 1
data.each { |item| num_combinaison = num_combinaison * item.length }
result = []
for i in 1..num_combinaison do
result.push entries.join()
end
num_repetition = num_combinaison
data.each_index do |index|
item = Array.new(data[index])
num_repetition = num_repetition / item.length
for i in 1..num_combinaison do
result[i-1].gsub!(entries[index], item[0])
if i % num_repetition == 0
item.shift
item = Array.new(data[index]) if item.length == 0
end
end
end
我确信有最佳方法可以做到这一点,但我找不到它。我试图使用产品或压扁功能但没有成功。
有人看到了最佳解决方案吗?
感谢您的帮助。
埃里克
答案 0 :(得分:4)
class Array
def * other; product(other).map(&:join) end
end
["a", "b", "c"] * ["1", "2"] * ["&", "(", "$"]
# =>
# ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", "b1&", "b1(", "b1$", "b2&",
# "b2(", "b2$", "c1&", "c1(", "c1$", "c2&", "c2(", "c2$"]
答案 1 :(得分:3)
您可以使用的最佳算法由Array#product
方法实现:
data = [["a", "b", "c"], ["1", "2"], ["&", "(", "$"]]
data.first.product(*entries.drop(1)).map(&:join)
# => ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", ...
<强>更新强>
一个更安全的替代方案,如果NoMethodError
是emtpy,我的第一个解决方案会引发data
:
data.reduce { |result, ary| result.product(ary).map(&:join) }
# => ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", ...
[].reduce { |r, a| r.product(a).map(&:join) }
# => nil