method
sample
v1_9_2_180 -
Show latest stable
- Class:
Array
sample(p1)public
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.
static VALUE
rb_ary_sample(int argc, VALUE *argv, VALUE ary)
{
VALUE nv, result, *ptr;
long n, len, i, j, k, idx[10];
len = RARRAY_LEN(ary);
if (argc == 0) {
if (len == 0) return Qnil;
i = len == 1 ? 0 : (long)(rb_genrand_real()*len);
return RARRAY_PTR(ary)[i];
}
rb_scan_args(argc, argv, "1", &nv);
n = NUM2LONG(nv);
if (n < 0) rb_raise(rb_eArgError, "negative sample number");
ptr = RARRAY_PTR(ary);
len = RARRAY_LEN(ary);
if (n > len) n = len;
switch (n) {
case 0: return rb_ary_new2(0);
case 1:
return rb_ary_new4(1, &ptr[(long)(rb_genrand_real()*len)]);
case 2:
i = (long)(rb_genrand_real()*len);
j = (long)(rb_genrand_real()*(len-1));
if (j >= i) j++;
return rb_ary_new3(2, ptr[i], ptr[j]);
case 3:
i = (long)(rb_genrand_real()*len);
j = (long)(rb_genrand_real()*(len-1));
k = (long)(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, ptr[i], ptr[j], ptr[k]);
}
if ((size_t)n < sizeof(idx)/sizeof(idx[0])) {
VALUE *ptr_result;
long sorted[sizeof(idx)/sizeof(idx[0])];
sorted[0] = idx[0] = (long)(rb_genrand_real()*len);
for (i=1; i<n; i++) {
k = (long)(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;
}
result = rb_ary_new2(n);
ptr_result = RARRAY_PTR(result);
for (i=0; i<n; i++) {
ptr_result[i] = ptr[idx[i]];
}
}
else {
VALUE *ptr_result;
result = rb_ary_new4(len, ptr);
ptr_result = RARRAY_PTR(result);
RB_GC_GUARD(ary);
for (i=0; i<n; i++) {
j = (long)(rb_genrand_real()*(len-i)) + i;
nv = ptr_result[j];
ptr_result[j] = ptr_result[i];
ptr_result[i] = nv;
}
}
ARY_SET_LEN(result, n);
return result;
} Related methods
- Instance methods
- &
- *
- +
- -
- <<
- <=>
- ==
- []
- []=
- abbrev
- assoc
- at
- clear
- collect
- collect!
- combination
- compact
- compact!
- concat
- count
- cycle
- dclone
- delete
- delete_at
- delete_if
- drop
- drop_while
- each
- each_index
- empty?
- eql?
- fetch
- fill
- find_index
- first
- flatten
- flatten!
- frozen?
- hash
- include?
- index
- initialize_copy
- insert
- inspect
- join
- keep_if
- last
- length
- map
- map!
- pack
- permutation
- pop
- pretty_print
- pretty_print_cycle
- product
- push
- rassoc
- reject
- reject!
- repeated_combination
- repeated_permutation
- replace
- reverse
- reverse!
- reverse_each
- rindex
- rotate
- rotate!
- sample
- select
- select!
- shelljoin
- shift
- shuffle
- shuffle!
- size
- slice
- slice!
- sort
- sort!
- sort_by!
- take
- take_while
- to_a
- to_ary
- to_csv
- to_s
- transpose
- uniq
- uniq!
- unshift
- values_at
- zip
- |
- Class methods
- []
- new
- try_convert