зеркало из https://github.com/github/ruby.git
Implement Array#minmax
Array#minmax was previous not implemented, so calling #minmax on array was actually calling Enumerable#minmax. This is a simple implementation of #minmax by just calling rb_ary_min and rb_ary_max, which improves performance significantly. Fixes [Bug #15929]
This commit is contained in:
Родитель
649753b7f5
Коммит
ced640951b
21
array.c
21
array.c
|
@ -4850,6 +4850,26 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ary.minmax -> [obj, obj]
|
||||||
|
* ary.minmax {| a,b | block } -> [obj, obj]
|
||||||
|
*
|
||||||
|
* Returns a two element array which contains the minimum and the
|
||||||
|
* maximum value in the array.
|
||||||
|
*
|
||||||
|
* Can be given an optional block to override the default comparison
|
||||||
|
* method <code>a <=> b</code>.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
rb_ary_minmax(VALUE ary)
|
||||||
|
{
|
||||||
|
if (rb_block_given_p()) {
|
||||||
|
return rb_call_super(0, NULL);
|
||||||
|
}
|
||||||
|
return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
push_value(st_data_t key, st_data_t val, st_data_t ary)
|
push_value(st_data_t key, st_data_t val, st_data_t ary)
|
||||||
{
|
{
|
||||||
|
@ -6902,6 +6922,7 @@ Init_Array(void)
|
||||||
|
|
||||||
rb_define_method(rb_cArray, "max", rb_ary_max, -1);
|
rb_define_method(rb_cArray, "max", rb_ary_max, -1);
|
||||||
rb_define_method(rb_cArray, "min", rb_ary_min, -1);
|
rb_define_method(rb_cArray, "min", rb_ary_min, -1);
|
||||||
|
rb_define_method(rb_cArray, "minmax", rb_ary_minmax, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
|
rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
|
||||||
rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
|
rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
|
||||||
|
|
|
@ -1792,6 +1792,25 @@ class TestArray < Test::Unit::TestCase
|
||||||
assert_same(obj, [obj, 1.0].max)
|
assert_same(obj, [obj, 1.0].max)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_minmax
|
||||||
|
assert_equal([1, 3], [1, 2, 3, 1, 2].minmax)
|
||||||
|
assert_equal([3, 1], [1, 2, 3, 1, 2].minmax {|a,b| b <=> a })
|
||||||
|
cond = ->((a, ia), (b, ib)) { (b <=> a).nonzero? or ia <=> ib }
|
||||||
|
assert_equal([[3, 2], [1, 3]], [1, 2, 3, 1, 2].each_with_index.minmax(&cond))
|
||||||
|
ary = %w(albatross dog horse)
|
||||||
|
assert_equal(["albatross", "horse"], ary.minmax)
|
||||||
|
assert_equal(["dog", "albatross"], ary.minmax {|a,b| a.length <=> b.length })
|
||||||
|
assert_equal([1, 3], [3,2,1].minmax)
|
||||||
|
|
||||||
|
class << (obj = Object.new)
|
||||||
|
def <=>(x) 1 <=> x end
|
||||||
|
def coerce(x) [x, 1] end
|
||||||
|
end
|
||||||
|
ary = [obj, 1.0].minmax
|
||||||
|
assert_same(obj, ary[0])
|
||||||
|
assert_equal(obj, ary[1])
|
||||||
|
end
|
||||||
|
|
||||||
def test_uniq
|
def test_uniq
|
||||||
a = []
|
a = []
|
||||||
b = a.uniq
|
b = a.uniq
|
||||||
|
|
Загрузка…
Ссылка в новой задаче