mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Moved Array#sample to rbinc
This commit is contained in:
parent
29eb1b1602
commit
d4e1d4e94e
3 changed files with 45 additions and 62 deletions
53
array.c
53
array.c
|
@ -5337,10 +5337,6 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPTHASH_GIVEN_P(opts) \
|
|
||||||
(argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
|
|
||||||
static ID id_random;
|
|
||||||
|
|
||||||
#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
|
#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -5373,55 +5369,16 @@ rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* call-seq:
|
|
||||||
* ary.sample -> obj
|
|
||||||
* ary.sample(random: rng) -> obj
|
|
||||||
* ary.sample(n) -> new_ary
|
|
||||||
* ary.sample(n, random: rng) -> new_ary
|
|
||||||
*
|
|
||||||
* Choose a random element or +n+ random elements from the array.
|
|
||||||
*
|
|
||||||
* The elements are chosen by using random and unique indices into the array
|
|
||||||
* in order to ensure that an element doesn't repeat itself unless the array
|
|
||||||
* already contained duplicate elements.
|
|
||||||
*
|
|
||||||
* If the array is empty the first form returns +nil+ and the second form
|
|
||||||
* returns an empty array.
|
|
||||||
*
|
|
||||||
* a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
|
|
||||||
* a.sample #=> 7
|
|
||||||
* a.sample(4) #=> [6, 4, 2, 5]
|
|
||||||
*
|
|
||||||
* The optional +rng+ argument will be used as the random number generator.
|
|
||||||
*
|
|
||||||
* a.sample(random: Random.new(1)) #=> 6
|
|
||||||
* a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_sample(int argc, VALUE *argv, VALUE ary)
|
rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
|
||||||
{
|
{
|
||||||
VALUE nv, result;
|
VALUE result;
|
||||||
VALUE opts, randgen = rb_cRandom;
|
|
||||||
long n, len, i, j, k, idx[10];
|
long n, len, i, j, k, idx[10];
|
||||||
long rnds[numberof(idx)];
|
long rnds[numberof(idx)];
|
||||||
long memo_threshold;
|
long memo_threshold;
|
||||||
|
|
||||||
if (OPTHASH_GIVEN_P(opts)) {
|
|
||||||
VALUE rnd;
|
|
||||||
ID keyword_ids[1];
|
|
||||||
|
|
||||||
keyword_ids[0] = id_random;
|
|
||||||
rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
|
|
||||||
if (rnd != Qundef) {
|
|
||||||
randgen = rnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len = RARRAY_LEN(ary);
|
len = RARRAY_LEN(ary);
|
||||||
if (rb_check_arity(argc, 0, 1) == 0) {
|
if (!to_array) {
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
i = 0;
|
i = 0;
|
||||||
else
|
else
|
||||||
|
@ -5429,7 +5386,6 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
|
||||||
|
|
||||||
return rb_ary_elt(ary, i);
|
return rb_ary_elt(ary, i);
|
||||||
}
|
}
|
||||||
nv = argv[0];
|
|
||||||
n = NUM2LONG(nv);
|
n = NUM2LONG(nv);
|
||||||
if (n < 0) rb_raise(rb_eArgError, "negative sample number");
|
if (n < 0) rb_raise(rb_eArgError, "negative sample number");
|
||||||
if (n > len) n = len;
|
if (n > len) n = len;
|
||||||
|
@ -7003,7 +6959,6 @@ Init_Array(void)
|
||||||
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
|
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
|
||||||
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
|
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
|
||||||
rb_define_method(rb_cArray, "count", rb_ary_count, -1);
|
rb_define_method(rb_cArray, "count", rb_ary_count, -1);
|
||||||
rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
|
|
||||||
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
|
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
|
||||||
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
|
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
|
||||||
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
|
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
|
||||||
|
@ -7025,8 +6980,6 @@ Init_Array(void)
|
||||||
rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
|
rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
|
||||||
|
|
||||||
rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
|
rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
|
||||||
|
|
||||||
id_random = rb_intern("random");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "array.rbinc"
|
#include "array.rbinc"
|
||||||
|
|
27
array.rb
27
array.rb
|
@ -33,4 +33,31 @@ class Array
|
||||||
def shuffle(random: Random)
|
def shuffle(random: Random)
|
||||||
__builtin_rb_ary_shuffle(random);
|
__builtin_rb_ary_shuffle(random);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# call-seq:
|
||||||
|
# ary.sample -> obj
|
||||||
|
# ary.sample(random: rng) -> obj
|
||||||
|
# ary.sample(n) -> new_ary
|
||||||
|
# ary.sample(n, random: rng) -> new_ary
|
||||||
|
#
|
||||||
|
# Choose a random element or +n+ random elements from the array.
|
||||||
|
#
|
||||||
|
# The elements are chosen by using random and unique indices into the array
|
||||||
|
# in order to ensure that an element doesn't repeat itself unless the array
|
||||||
|
# already contained duplicate elements.
|
||||||
|
#
|
||||||
|
# If the array is empty the first form returns +nil+ and the second form
|
||||||
|
# returns an empty array.
|
||||||
|
#
|
||||||
|
# a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
|
||||||
|
# a.sample #=> 7
|
||||||
|
# a.sample(4) #=> [6, 4, 2, 5]
|
||||||
|
#
|
||||||
|
# The optional +rng+ argument will be used as the random number generator.
|
||||||
|
#
|
||||||
|
# a.sample(random: Random.new(1)) #=> 6
|
||||||
|
# a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
|
||||||
|
def sample(n = (ary = false), random: Random)
|
||||||
|
__builtin_rb_ary_sample(random, n, ary)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,21 +65,24 @@ describe "Array#sample" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with options" do
|
describe "with options" do
|
||||||
it "calls #to_hash to convert the passed Object" do
|
ruby_version_is ""..."2.8" do
|
||||||
obj = mock("array_sample")
|
# keyword argument since 2.8
|
||||||
obj.should_receive(:to_hash).and_return({})
|
it "calls #to_hash to convert the passed Object" do
|
||||||
obj.should_not_receive(:to_int)
|
obj = mock("array_sample")
|
||||||
|
obj.should_receive(:to_hash).and_return({})
|
||||||
|
obj.should_not_receive(:to_int)
|
||||||
|
|
||||||
[1, 2].sample(obj).should be_an_instance_of(Fixnum)
|
[1, 2].sample(obj).should be_an_instance_of(Fixnum)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
|
it "calls #to_int on the first argument and #to_hash on the second when passed Objects" do
|
||||||
count = mock("array_sample_count")
|
count = mock("array_sample_count")
|
||||||
count.should_receive(:to_int).and_return(2)
|
count.should_receive(:to_int).and_return(2)
|
||||||
options = mock("array_sample_options")
|
options = mock("array_sample_options")
|
||||||
options.should_receive(:to_hash).and_return({})
|
options.should_receive(:to_hash).and_return({})
|
||||||
|
|
||||||
[1, 2].sample(count, options).size.should == 2
|
[1, 2].sample(count, options).size.should == 2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls #rand on the Object passed by the :random key in the arguments Hash" do
|
it "calls #rand on the Object passed by the :random key in the arguments Hash" do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue