List comprehensions: Difference between revisions

Content added Content deleted
(Added Go)
(→‎{{header|Ruby}}: Removed outdated Ruby 1.8.6 code)
Line 2,125: Line 2,125:


Ruby's object-oriented style enforces writing 1..100 before x. Think not of x in 1..100. Think of 1..100 giving x.
Ruby's object-oriented style enforces writing 1..100 before x. Think not of x in 1..100. Think of 1..100 giving x.

There is no elegant way to comprise a list from multiple variables. Pythagorean triplets need three variables, with 1..n giving x, then x..n giving y, then y..n giving z. A less than elegant way is to nest three blocks.


=== Ruby 1.9.2 ===
=== Ruby 1.9.2 ===
Line 2,150: Line 2,148:
* The outer <tt>(1..n).flat_map { ... }</tt> concatenates the middle arrays for all x.
* The outer <tt>(1..n).flat_map { ... }</tt> concatenates the middle arrays for all x.


=== Ruby 1.8.6 ===
{{works with|Ruby|1.8.6 or later}}

<lang ruby>n = 20

unless Enumerable.method_defined? :flat_map
module Enumerable
def flat_map
inject([]) { |a, x| a.concat yield(x) }
end
end
end

unless Array.method_defined? :keep_if
class Array
def keep_if
delete_if { |x| not yield(x) }
end
end
end
# select Pythagorean triplets
r = ((1..n).flat_map { |x|
(x..n).flat_map { |y|
(y..n).flat_map { |z|
[[x, y, z]].keep_if { x * x + y * y == z * z }}}})

p r # print the array _r_</lang>


This is the exact same code, except that it now defines Enumerable#flat_map and Array#keep_if when those methods are missing. It now works with older versions of Ruby, like 1.8.6.


Illustrating a way to avoid all loops (but no list comprehensions) :
Illustrating a way to avoid all loops (but no list comprehensions) :