summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-03-23 12:12:32 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-03-23 12:12:32 +0900
commitff6666632f96fe837cc36b13afac8f2ab147d9d7 (patch)
tree88f91fe5453e60608758f76787e48bc354563e3c
parentbbee56f284f3c0df94fe7ec9ad116b266f7f5edd (diff)
parent5b31ee9a2ab463561ee8793ab6387d2ca2c6e21f (diff)
downloadmruby-ff6666632f96fe837cc36b13afac8f2ab147d9d7.tar.gz
mruby-ff6666632f96fe837cc36b13afac8f2ab147d9d7.zip
Merge pull request #1920 from suzukaze/add-enum.minmax_by
Add Enumerable#minmax_by
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb39
-rw-r--r--mrbgems/mruby-enum-ext/test/enum.rb4
2 files changed, 43 insertions, 0 deletions
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb
index 873de1fbc..8a2cdd5f1 100644
--- a/mrbgems/mruby-enum-ext/mrblib/enum.rb
+++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb
@@ -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
diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb
index 2f7ed7aaa..4dfa2fec0 100644
--- a/mrbgems/mruby-enum-ext/test/enum.rb
+++ b/mrbgems/mruby-enum-ext/test/enum.rb
@@ -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