Reputation: 317
I have an array to give a set of ranges like range = [[10,15], [7,13], [2,3]..]
. I have nested iteration blocks using these ranges like below.
(10..15).each{|i|
(7..13).each{|j|
(2..3).each{|k|
puts "#{k} - #{j} - #{i}"
}
}
}
I have to form these nested loops dynamically based on size of the range array's size and their elements. I guess I should dynamically define a method by framing above iterations block and call the method to do the job. But I am not able to code this. Your help is much appreciated.
Upvotes: 3
Views: 84
Reputation: 368944
Using Array#product
:
range = [[10, 15], [7, 13], [2, 3]]
range = range.map { |a,b| (a..b).to_a }
# range is now `[[10, 11, 12, 13, 14, 15], [7, 8, 9, 10, 11, 12, 13], [2, 3]]`
range[0].product(*range[1..-1]) { |xs|
puts xs.join(' - ')
}
output:
10 - 7 - 2
10 - 7 - 3
10 - 8 - 2
...
15 - 12 - 3
15 - 13 - 2
15 - 13 - 3
UPDATE according to OP's comment. If you use older version of ruby that does not have Array#product
, use following:
class Array
def product(*others)
if others.empty?
each {|x| yield [x] }
else
each {|x| others[0].product(*others[1..-1]) { |ys| yield [x] + ys }}
end
end
end
Upvotes: 3
Reputation: 16506
range = [[10,15], [7,13], [3,2]]
count = 0
str = ''
def dyn_levels(count, range)
(range[count][0]..range[count][1]).each do |i|
str.insert(str.size,i)
if count < range.size
str.insert(str.size,'-')
count+=1
dyn_level(count, range)
end
end
end
str.reverse!
Upvotes: 0