Skip to content

Instantly share code, notes, and snippets.

@jackwillis
Last active August 29, 2015 14:22
Show Gist options
  • Save jackwillis/c7e3020ac22ac7076262 to your computer and use it in GitHub Desktop.
Save jackwillis/c7e3020ac22ac7076262 to your computer and use it in GitHub Desktop.
List comprehension look-alike in Ruby
class Hash
# http://stackoverflow.com/a/14881438/3551701
def product
product = values[0].product(*values[1..-1])
product.map {|p| Hash[keys.zip(p)] }
end
end
class Proc
# http://stackoverflow.com/a/10059209/3551701
def eval_with_hash(h)
Struct.new(*h.keys).new(*h.values).instance_exec(&self)
end
def for(params, &predicate)
eager_params = Hash[params.map {|k, v| [k, v.to_a] }]
lines = eager_params.product
lines = lines.select {|h| predicate.eval_with_hash(h) } if predicate
lines.map {|h| eval_with_hash(h) }
end
end
# Python for comparison:
# [ (x,y) for x in range(3) for y in range(3) if x != y ] #=> [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
->{ [x, y] }.for(x: 0..2, y: 0..2) { x != y } #=> [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]
Person = Struct.new(:name, :age)
people = [
Person.new("Alice", 42),
Person.new("Bob", 24),
Person.new("Eve", 16)
]
# Idiomatic Ruby:
people.select {|person| person.age > 18 }.map(&:name) #=> ["Alice", "Bob"]
# With this method:
->{ person.name }.for(person: people) { person.age > 18 } #=> ["Alice", "Bob"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment