[macruby-changes] [1761] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jun 5 18:18:14 PDT 2009
Revision: 1761
http://trac.macosforge.org/projects/ruby/changeset/1761
Author: lsansonetti at apple.com
Date: 2009-06-05 18:18:12 -0700 (Fri, 05 Jun 2009)
Log Message:
-----------
deleted Array#choice and added Array#sample, removing related tag files since the specs pass
Modified Paths:
--------------
MacRuby/branches/experimental/array.c
Removed Paths:
-------------
MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/choice_tags.txt
MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/sample_tags.txt
Modified: MacRuby/branches/experimental/array.c
===================================================================
--- MacRuby/branches/experimental/array.c 2009-06-06 00:09:08 UTC (rev 1760)
+++ MacRuby/branches/experimental/array.c 2009-06-06 01:18:12 UTC (rev 1761)
@@ -2997,21 +2997,99 @@
/*
* call-seq:
- * array.choice -> obj
+ * array.sample -> obj
+ * array.sample(n) -> an_array
*
- * Choose a random element from an array.
+ * Choose a random element, or the random +n+ elements, from the array.
+ * If the array is empty, the first form returns <code>nil</code>, and the
+ * second form returns an empty array.
*/
static VALUE
-rb_ary_choice(VALUE ary, SEL sel)
+rb_ary_sample(VALUE ary, SEL sel, int argc, VALUE *argv)
{
- long i, j;
+ VALUE nv, result;
+ long n, len, i, j, k, idx[10];
- i = RARRAY_LEN(ary);
- if (i == 0) return Qnil;
- j = rb_genrand_real()*i;
- return RARRAY_AT(ary, j);
+ len = RARRAY_LEN(ary);
+ if (argc == 0) {
+ if (len == 0) {
+ return Qnil;
+ }
+ i = len == 1 ? 0 : rb_genrand_real() * len;
+ return RARRAY_AT(ary, i);
+ }
+ rb_scan_args(argc, argv, "1", &nv);
+ n = NUM2LONG(nv);
+ len = RARRAY_LEN(ary);
+ if (n > len) {
+ n = len;
+ }
+ switch (n) {
+ case 0:
+ return rb_ary_new2(0);
+
+ case 1:
+ nv = RARRAY_AT(ary, (long)(rb_genrand_real() * len));
+ return rb_ary_new4(1, &nv);
+
+ case 2:
+ i = rb_genrand_real() * len;
+ j = rb_genrand_real() * (len - 1);
+ if (j >= i) {
+ j++;
+ }
+ return rb_ary_new3(2, RARRAY_AT(ary, i), RARRAY_AT(ary, j));
+
+ case 3:
+ i = rb_genrand_real() * len;
+ j = rb_genrand_real() * (len - 1);
+ k = rb_genrand_real() * (len - 2);
+ {
+ long l = j, g = i;
+ if (j >= i) {
+ l = i;
+ g = ++j;
+ }
+ if (k >= l && (++k >= g)) {
+ ++k;
+ }
+ }
+ return rb_ary_new3(3, RARRAY_AT(ary, i), RARRAY_AT(ary, j),
+ RARRAY_AT(ary, k));
+ }
+ if (n < sizeof(idx) / sizeof(idx[0])) {
+ long sorted[sizeof(idx) / sizeof(idx[0])];
+ sorted[0] = idx[0] = rb_genrand_real()*len;
+ for (i = 1; i < n; i++) {
+ k = rb_genrand_real() * --len;
+ for (j = 0; j < i; ++j) {
+ if (k < sorted[j]) {
+ break;
+ }
+ ++k;
+ }
+ memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
+ sorted[j] = idx[i] = k;
+ }
+ VALUE *elems = (VALUE *)alloca(sizeof(VALUE) * n);
+ for (i = 0; i < n; i++) {
+ elems[i] = RARRAY_AT(ary, idx[i]);
+ }
+ result = rb_ary_new4(n, elems);
+ }
+ else {
+ VALUE *elems = (VALUE *)alloca(sizeof(VALUE) * n);
+ for (i = 0; i < n; i++) {
+ j = (long)(rb_genrand_real() * (len - i)) + i;
+ nv = RARRAY_AT(ary, j);
+ elems[i] = nv;
+ }
+ result = rb_ary_new4(n, elems);
+ }
+
+ return result;
}
@@ -3658,7 +3736,7 @@
rb_objc_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
rb_objc_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
- rb_objc_define_method(rb_cArray, "choice", rb_ary_choice, 0);
+ rb_objc_define_method(rb_cArray, "sample", rb_ary_sample, -1);
rb_objc_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
rb_objc_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
rb_objc_define_method(rb_cArray, "combination", rb_ary_combination, 1);
Deleted: MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/choice_tags.txt
===================================================================
--- MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/choice_tags.txt 2009-06-06 00:09:08 UTC (rev 1760)
+++ MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/choice_tags.txt 2009-06-06 01:18:12 UTC (rev 1761)
@@ -1 +0,0 @@
-fails:Array#choice raises NoMethodError
\ No newline at end of file
Deleted: MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/sample_tags.txt
===================================================================
--- MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/sample_tags.txt 2009-06-06 00:09:08 UTC (rev 1760)
+++ MacRuby/branches/experimental/spec/frozen/tags/macruby/core/array/sample_tags.txt 2009-06-06 01:18:12 UTC (rev 1761)
@@ -1,8 +0,0 @@
-fails:Array#sample selects a random value from the array
-fails:Array#sample returns nil for empty arrays
-fails:Array#sample passed a number n as an argument raises ArgumentError for a negative n
-fails:Array#sample passed a number n as an argument returns different random values from the array
-fails:Array#sample passed a number n as an argument tries to convert n to an Integer using #to_int
-fails:Array#sample passed a number n as an argument returns all values with n big enough
-fails:Array#sample passed a number n as an argument returns [] for empty arrays or if n <= 0
-fails:Array#sample passed a number n as an argument does not return subclass instances with Array subclass
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090605/05a7e2a4/attachment.html>
More information about the macruby-changes
mailing list