summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-12 05:08:52 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-12 05:08:52 +0000
commite65c07e98b1b076ab99a2b12043148b3b4962386 (patch)
tree66825c27aa6002a3ef252c9aee08417dcbff17f8 /array.c
parentaadf534bb33a9698cf1521afe675a7a90d0becff (diff)
* array.c (rb_ary_sample): rename #choice to #sample. in
addition, sample takes optional argument, a la #first. * random.c (Init_Random): always initialize seed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@18509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r--array.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/array.c b/array.c
index 7e8c12b683..9bd5e0bff3 100644
--- a/array.c
+++ b/array.c
@@ -3301,22 +3301,51 @@ 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 <code>nil</code>, and the
+ * second form returns an empty array.
*
- * Choose a random element from an array.
*/
static VALUE
-rb_ary_choice(ary)
+rb_ary_sample(argc, argv, ary)
+ int argc;
+ VALUE *argv;
VALUE ary;
{
- long i, j;
+ VALUE nv, result;
+ int n, len, i, j;
- i = RARRAY(ary)->len;
- if (i == 0) return Qnil;
- j = rb_genrand_real()*i;
- return RARRAY(ary)->ptr[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<n; i++) {
+ retry:
+ j = rb_genrand_real()*len;
+ nv = LONG2NUM(j);
+ for (j=0; j<i; j++) {
+ if (RARRAY_PTR(result)[j] == nv)
+ goto retry;
+ }
+ RARRAY_PTR(result)[i] = nv;
+ RARRAY(result)->len = i+1;
+ }
+ for (i=0; i<n; i++) {
+ nv = RARRAY_PTR(result)[i];
+ RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[NUM2LONG(nv)];
+ }
+ return result;
}
@@ -3852,7 +3881,7 @@ Init_Array()
rb_define_method(rb_cArray, "count", rb_ary_count, -1);
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
- rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
+ 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, "permutation", rb_ary_permutation, -1);
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);