Let's say I have the following array:
arr = [[5, 1], [2, 7]]
and I want to find the minimum element, comparing the second element of the elements. The minimum element will be [5, 1]
since 1
is less than 7
. I can use the following code:
arr.min {|a,b| a[1] <=> b[1]}
For calculating the maximum, I can do the same:
arr.max {|a,b| a[1] <=> b[1]}
That gives [2, 7]
.
I use the same block all the time. I would like to have that block somewhere and provide it to the min/max function. I hoped something like:
blo = lambda {|a,b| a[1] <=> b[1]}
arr.min blo
would work, but it didn't. Any idea on how I can do this?
A more general solution to problems like this is to avoid nested arrays entirely and use a class instead. You can then define the <=> operator for that class, giving you access to all the functions in the Comparable mixin (http://ruby-doc.org/core/classes/Comparable.html) gives you the <, <=, ==, >=, and > operators and the method 'between?'
This is just an example, in real life you would use classes that describe what they store:
class Duo
include Comparable
def initialize( a, b )
@a = a
@b = b
end
def <=>(rhs)
@b <=> rhs.b
end
end
If you have an array of Duo object you can then use the min, max, and sort functions without having to define the comparison operator. So...
@a = Duo.new( 1, 10 )
@b = Duo.new( 2, 5 )
@c = Duo.new( 3, 1 )
[ @a, @b, @c ].sort
would return the array [ @c, @b, @a ]
And
[@a, @b, @c].max
would return @a
This is much more the 'Ruby Way' than nested data-structures with logic that relies on positions in arrays. It takes slightly more work at the start, but you'll find it much better in the long run.
Ruby is a very object oriented programming language and provides very powerful tools for you to use. I thoroughly recommend reading a book like "The Ruby Programming Language" or "The Ruby Way" to get a proper overview of the power of the language.
Use the &
operator to turn a Proc
object into a block.
arr.min &blo
@sepp2k's answer is the more general one, but in your specific case, I would just use
arr.min_by(&:last)
arr.max_by(&:last)
since that is much more obvious than all those curly braces and square brackets and array indices floating around.
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