# Method: Array#combination

Defined in:
array.c

### - (Object) combination(n) {|c| ... }- (Enumerator) combination(n)

When invoked with a block, yields all combinations of length n of elements from the array and then returns the array itself.

The implementation makes no guarantees about the order in which the combinations are yielded.

If no block is given, an Enumerator is returned instead.

Examples:

``````a = [1, 2, 3, 4]
a.combination(1).to_a  #=> [[1],[2],[3],[4]]
a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
a.combination(4).to_a  #=> [[1,2,3,4]]
a.combination(0).to_a  #=> [[]] # one combination of length 0
a.combination(5).to_a  #=> []   # no combinations of length 5``````

 ``` 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925``` ```# File 'array.c', line 4878 static VALUE rb_ary_combination(VALUE ary, VALUE num) { long n, i, 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 < len; i++) { rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i))); } } else { volatile VALUE t0 = tmpbuf(n+1, sizeof(long)); long *stack = (long*)RSTRING_PTR(t0); volatile VALUE cc = tmpary(n); VALUE *chosen = RARRAY_PTR(cc); long lev = 0; MEMZERO(stack, long, n); stack[0] = -1; for (;;) { chosen[lev] = RARRAY_AREF(ary, stack[lev+1]); for (lev++; lev < n; lev++) { chosen[lev] = RARRAY_AREF(ary, stack[lev+1] = stack[lev]+1); } rb_yield(rb_ary_new4(n, chosen)); if (RBASIC(t0)->klass) { rb_raise(rb_eRuntimeError, "combination reentered"); } do { if (lev == 0) goto done; stack[lev--]++; } while (stack[lev+1]+n == len+lev+1); } done: tmpbuf_discard(t0); tmpary_discard(cc); } return ary; }```