[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