End of Life Ruby 3.0 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
instance method
Array#permutation
array.permutation {|element| ... } → self
array.permutation(n) {|element| ... } → self
array.permutation → new_enumerator
array.permutation(n) → new_enumerator
array.c
View on GitHub ↗
static VALUE
rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
{
long r, n, i;
n = RARRAY_LEN(ary); /* Array length */
RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
r = n;
if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
r = NUM2LONG(argv[0]); /* Permutation size from argument */
if (r < 0 || n < r) {
/* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else { /* this is the general case */
volatile VALUE t0;
long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
char *used = (char*)(p + r);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
RBASIC_CLEAR_CLASS(ary0);
MEMZERO(used, char, n); /* initialize array */
permute0(n, r, p, used, ary0); /* compute and yield permutations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
When invoked with a block, yield all permutations of elements of self; returns self. The order of permutations is indeterminate.
When a block and an in-range positive Integer argument n (0 < n <= self.size) are given, calls the block with all n-tuple permutations of self.
Example:
Example
a = [0, 1, 2] a.permutation(2) {|permutation| p permutation }
Output:
Example
[0, 1] [0, 2] [1, 0] [1, 2] [2, 0] [2, 1]
Another example:
Example
a = [0, 1, 2] a.permutation(3) {|permutation| p permutation }
Output:
Example
[0, 1, 2] [0, 2, 1] [1, 0, 2] [1, 2, 0] [2, 0, 1] [2, 1, 0]
When n is zero, calls the block once with a new empty Array:
Example
a = [0, 1, 2] a.permutation(0) {|permutation| p permutation }
Output:
Example
[]
When n is out of range (negative or larger than self.size), does not call the block:
Example
a = [0, 1, 2] a.permutation(-1) {|permutation| fail 'Cannot happen' } a.permutation(4) {|permutation| fail 'Cannot happen' }
When a block given but no argument, behaves the same as a.permutation(a.size):
Example
a = [0, 1, 2] a.permutation {|permutation| p permutation }
Output:
Example
[0, 1, 2] [0, 2, 1] [1, 0, 2] [1, 2, 0] [2, 0, 1] [2, 1, 0]
Returns a new Enumerator if no block given:
Example
a = [0, 1, 2] a.permutation # => #<Enumerator: [0, 1, 2]:permutation> a.permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>