Notes posted to Ruby
RSS feedOptional Argument for detect/find [Not Documented]
detect/find’s optional argument lets you specify a proc or lambda whose return value will be the result in cases where no object in the collection matches the criteria.
classic_rock_bands = ["AC/DC", "Black Sabbath","Queen", "Ted Nugent and the Amboy Dukes","Scorpions", "Van Halen"] default_band = Proc.new {"ABBA"} classic_rock_bands.find(default_band) {|band| band > "Van Halen"} => "ABBA"
or
random_band = lambda do fallback_bands = ["Britney Spears", "Christina Aguilera", "Ashlee Simpson"] fallback_bands[rand(fallback_bands.size)] end classic_rock_bands.find(random_band) {|band| band > "Van Halen"} => "Britney Spears"
Convert a Hash to an Array of Arrays using map
Although you‘ll always have to_a and it‘s faster, this trick is too cool to ignore…
Convert a Hash to an Array of Arrays using Enumerable#map
Convert a Hash to an Array of Arrays using map
Although you’ll always have to_a and it’s faster, this trick is too cool to ignore…
When the block is omitted, collect or map uses this implied block: {|item| item}, which means when applied on an hash without a block, collect/map returns an array containing a set of two-item arrays, one for each key/value pair in the hash. For each two-item array, item 0 is the key and item 1 is the corresponding value.
burgers = {"Big Mac" => 300, "Whopper with cheese" => 450, "Wendy's Double with cheese" => 320} burgers.map => [["Wendy's Double with cheese", 320], ["Big Mac", 300], ["Whopper with cheese", 450]]
see also:
Using any? on Empty Arrays and Hashes
When applied to an empty array or hash, with or without a block, any? always returns false. That’s because with an empty collection, there are no values to process and return a true value.
Testing Arrays for nils with Enumerable#all?
When the block is omitted, all? uses this implied block: {|item| item}.
Since everything in Ruby evaluates to true except for false and nil, using all? without a block on an array is effectively a test to see if all the items in the collection evaluate to true (or conversely, if there are any false or nil values in the array).
Using all? without a block on a hash is meaningless, as it will always return true.
Enumerable#all? and Hashes
When used on a hash and a block is provided, all? passes each key/value pair as a two-element array to the block, which you can “catch” as either:
-
A two-element array, with the key in element 0 and its corresponding value in element 1, or
-
Two separate items, the first being the key, the second being the corresponding value.
Using all? on Empty Arrays and Hashes
When applied to an empty array or hash, with or without a block, all? always returns true. That’s because with an empty collection, there are no values to process and return a false value. so, watch out, if your array or hash is empty for any reason you will get a true which might not be what you expect it to be.
Convert an Array to a Hash
The Hash.[] method converts an even number of parameters to a Hash. (The Hash[] method depends on the Hash class, but don’t confuse the method with the class itself). For example:
Hash['A', 'a', 'B', 'b'] # => {"A"=>"a", "B"=>"b"}
You can convert an array to a hash using the Hash[] method:
array = ['A', 'a', 'B', 'b', 'C', 'c'] hash = Hash[*array] # => {"A"=>"a", "B"=>"b", "C"=>"c"}
The * (splat) operator converts the array into an argument list, as expected by Hash[].
You can similarly convert an array of arrays to a Hash, by adding flatten:
array = [['A', 'a'], ['B', 'b'], ['C', 'c']] hash = Hash[*array.flatten] # => {"A"=>"a", "B"=>"b", "C"=>"c"}
This also comes in handy when you have a list of words that you want to convert to a Hash:
Hash[*%w( A a B b C c )] # => {"A"=>"a", "B"=>"b", "C"=>"c"}
Convert an Array of Arrays to a Hash using inject
Converting an array of arrays to a hash using inject:
array = [['A', 'a'], ['B', 'b'], ['C', 'c']] hash = array.inject({}) do |memo, values| memo[values.first] = values.last memo end hash # => {'A' => 'a', 'B' => 'b', 'C' => 'c'}