Method: Array#combination
- Defined in:
- array.c
#combination(count) {|element| ... } ⇒ self #combination(count) ⇒ Object
When a block and a positive integer-convertible object argument count
(0 < count <= self.size
) are given, calls the block with each combination of self
of size count
; returns self
:
a = %w[a b c] # => ["a", "b", "c"]
a.combination(2) {|combination| p combination } # => ["a", "b", "c"]
Output:
["a", "b"]
["a", "c"]
["b", "c"]
The order of the yielded combinations is not guaranteed.
When count
is zero, calls the block once with a new empty array:
a.combination(0) {|combination| p combination }
[].combination(0) {|combination| p combination }
Output:
[]
[]
When count
is negative or larger than self.size
and self
is non-empty, does not call the block:
a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
With no block given, returns a new Enumerator.
Related: Array#permutation; see also Methods for Iterating.
7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 |
# File 'array.c', line 7218
static VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
long i, n, len;
n = NUM2LONG(num);
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
len = RARRAY_LEN(ary);
if (n < 0 || len < n) {
/* yield nothing */
}
else if (n == 0) {
rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else {
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
volatile VALUE t0;
long *stack = ALLOCV_N(long, t0, n+1);
RBASIC_CLEAR_CLASS(ary0);
combinate0(len, n, stack, ary0);
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
|