mlatu mlatu - 7 months ago 8
Ruby Question

Does Ruby have something like Python's list comprehensions?

Python has a nice feature:

print([j**2 for j in [2, 3, 4, 5]]) # => [4, 9, 16, 25]


In Ruby it's even simpler:

puts [2, 3, 4, 5].map{|j| j**2}


but if it's about nested loops Python looks more convenient.

In Python we can do this:

digits = [1, 2, 3]
chars = ['a', 'b', 'c']
print([str(d)+ch for d in digits for ch in chars if d >= 2 if ch == 'a'])
# => ['2a', '3a']


The equivalent in Ruby is:

digits = [1, 2, 3]
chars = ['a', 'b', 'c']
list = []
digits.each do |d|
chars.each do |ch|
list.push d.to_s << ch if d >= 2 && ch == 'a'
end
end
puts list


Does Ruby have something similar?

Answer

The common way in Ruby is to properly combine Enumerable and Array methods to achieve the same:

digits.product(chars).select{ |d, ch| d >= 2 && ch == 'a' }.map(&:join)

This is only 4 or so characters longer than the list comprehension and just as expressive (IMHO of course, but since list comprehensions are just a special application of the list monad, one could argue that it's probably possible to adequately rebuild that using Ruby's collection methods), while not needing any special syntax.

Comments