I am new to ruby language so when I was trying to sort a hash by value I used this method to sort:
movie_popularity.sort_by{|m,p| p}.reverse
but the the sort method returns an array while I need a hash to be returned so I used this command:
movie_popularity=Hash[*movie_popularity.sort_by{|m,p| p}.reverse.flatten]
my Question is what is the meaning of *
and flatten
in the above line?
Thanks =)
The flatten() is an inbuilt method in Ruby returns a new set that is a copy of the set, flattening each containing set recursively. Syntax: s1.flatten() Parameters: The function does not takes any parameter. Return Value: It returns a boolean value. It returns true if the set is empty or it returns false.
Flattening an Array with Recursion Like the single flatten, it checks if an element is an array, and if not, appends the value of the element to a results array. However, if the element is an array, the method calls itself pulling in this element and the existing results array.
inject accepts a symbol as a parameter, this symbol must be the name of a method or operator, which is this case is :+ so [1,2,3]. inject(:+) is passing each value to the method specified by the symbol, hence summing all elements in the array.
The *
is called the "splat operator"; I'm not sure I could give you the technical definition (though I'm sure you'd find it soon enough with Google's help), but the way I'd describe it is that it basically takes the place of hand-writing multiple comma-separated values in code.
To make this more concrete, consider the case of Hash[]
which you've used in your example. The Hash
class has a []
class method which takes a variable number of arguments and can normally be called like this:
# Returns { "foo" => 1, "bar" => 2 }
h = Hash["foo", 1, "bar", 2]
Notice how that isn't an array or a hash or anything that I passed in; it's a (hand-written) sequence of values. The *
operator allows you to achieve basically the same thing using an array--in your case, the one returned by movie_popularity.sort_by{|m,p| p}.reverse.flatten
.
As for that flatten
call: when you call sort_by
on a hash, you're really leveraging the Enumerable
module which is included in a variety of classes (most notably Array
and Hash
) that provide enumeration. In the case of a hash, you've probably noticed that instead of iterating over one like this:
hash.each { |value| ... }
Instead you do this:
hash.each { |key, value| ... }
That is, iterating over a hash yields two values on each iteration. So your sort_by
call on its own would return a sequence of pairs. Calling flatten
on this result collapses the pairs into a one-dimensional sequence of values, like this:
# Returns [1, 2, 3, 4]
[[1, 2], [3, 4]].flatten
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With