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.

Overloads:

  • #combination(count) {|element| ... } ⇒ self

    Yields:

    • (element)

    Returns:

    • (self)


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;
}