From 5027aaaf4e3d0ca8d64e15b704b20d92973db258 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sat, 22 Mar 2014 21:52:08 +0900 Subject: Add Enumerable#minmax --- mrbgems/mruby-enum-ext/mrblib/enum.rb | 37 +++++++++++++++++++++++++++++++++++ mrbgems/mruby-enum-ext/test/enum.rb | 6 ++++++ 2 files changed, 43 insertions(+) (limited to 'mrbgems/mruby-enum-ext') diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index 1849ff4cd..2f6c4dbbc 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -335,4 +335,41 @@ module Enumerable end min end + + ## + # call-seq: + # enum.minmax -> [min, max] + # enum.minmax { |a, b| block } -> [min, max] + # + # Returns two elements array which contains the minimum and the + # maximum value in the enumerable. The first form assumes all + # objects implement Comparable; the second uses the + # block to return a <=> b. + # + # a = %w(albatross dog horse) + # a.minmax #=> ["albatross", "horse"] + # a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"] + + def minmax(&block) + max = nil + min = nil + first = true + + self.each do |val| + if first + max = val + min = val + first = false + else + if block + max = val if block.call(val, max) > 0 + min = val if block.call(val, min) < 0 + else + max = val if (val <=> max) > 0 + min = val if (val <=> min) < 0 + 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 ba0851582..2f7ed7aaa 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -84,3 +84,9 @@ end assert("Enumerable#min_by") do assert_equal "dog", %w[albatross dog horse].min_by { |x| x.length } end + +assert("Enumerable#minmax") do + a = %w(albatross dog horse) + assert_equal ["albatross", "horse"], a.minmax + assert_equal ["dog", "albatross"], a.minmax { |a, b| a.length <=> b.length } +end -- cgit v1.2.3