Merge pull request #1920 from suzukaze/add-enum.minmax_by

Add Enumerable#minmax_by
This commit is contained in:
Yukihiro "Matz" Matsumoto
2014-03-23 12:12:32 +09:00
2 changed files with 43 additions and 0 deletions
+39
View File
@@ -374,4 +374,43 @@ module Enumerable
end
[min, max]
end
##
# call-seq:
# enum.minmax_by { |obj| block } -> [min, max]
# enum.minmax_by -> an_enumerator
#
# Returns a two element array containing the objects in
# <i>enum</i> that correspond to the minimum and maximum values respectively
# from the given block.
#
# If no block is given, an enumerator is returned instead.
#
# %w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"]
def minmax_by(&block)
max = nil
max_cmp = nil
min = nil
min_cmp = nil
first = true
self.each do |*val|
if first
max = min = val.__svalue
max_cmp = min_cmp = block.call(*val)
first = false
else
if (cmp = block.call(*val)) > max_cmp
max = val.__svalue
max_cmp = cmp
end
if (cmp = block.call(*val)) < min_cmp
min = val.__svalue
min_cmp = cmp
end
end
end
[min, max]
end
end
+4
View File
@@ -90,3 +90,7 @@ assert("Enumerable#minmax") do
assert_equal ["albatross", "horse"], a.minmax
assert_equal ["dog", "albatross"], a.minmax { |a, b| a.length <=> b.length }
end
assert("Enumerable#minmax_by") do
assert_equal ["dog", "albatross"], %w(albatross dog horse).minmax_by { |x| x.length }
end