diff --git a/ChangeLog b/ChangeLog index 5ba0e933e9..1f8e6188ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Aug 11 18:57:38 2008 Yukihiro Matsumoto + + * array.c (rb_ary_sample): rename #choice to #sample. in + addition, sample takes optional argument, a la #first. + Mon Aug 11 18:28:02 2008 Narihiro Nakamura * gc.c: added GC::Profiler. diff --git a/array.c b/array.c index 1d2202b815..23ff56d6f7 100644 --- a/array.c +++ b/array.c @@ -2998,21 +2998,48 @@ rb_ary_shuffle(VALUE ary) /* * call-seq: - * array.choice -> obj + * array.sample -> obj + * array.sample(n) -> an_array + * + * Choose a random element, or the random +n+ elements, fron the array. + * If the array is empty, the first form returns nil, and the + * second form returns an empty array. * - * Choose a random element from an array. */ static VALUE -rb_ary_choice(VALUE ary) +rb_ary_sample(int argc, VALUE *argv, VALUE ary) { - long i, j; + VALUE nv, result; + int n, len, i, j; - i = RARRAY_LEN(ary); - if (i == 0) return Qnil; - j = rb_genrand_real()*i; - return RARRAY_PTR(ary)[j]; + len = RARRAY_LEN(ary); + if (argc == 0) { + if (len == 0) return Qnil; + i = rb_genrand_real()*len; + return RARRAY_PTR(ary)[i]; + } + rb_scan_args(argc, argv, "1", &nv); + if (len == 0) return rb_ary_new2(0); + n = NUM2INT(nv); + result = rb_ary_new2(n); + for (i=0; i