max pleaner max pleaner - 5 months ago 16
Ruby Question

How can I get the length N combinations for an array using lazy evaluation?

I think I understand the difference between permutation and combination:

In short,

[1,20,30].permutation(3).map(&:sort).uniq
is the same as
[1,20,30].combination(3)
.

I currently have a program which gets all of an array's combinations:

array = [1,20,30,40,50,60]
1.upto(array.length).each do |combination_length|
array.combination(combination_length).each do |combination|
# ... do something here with the combination ...
end
end


I'm trying to reduce the memory consumption and I think I should find an alternative to
array.combination(combination_length).each
.

The Ruby docs for Lazy Enumerators don't seem to show a
combination
method. The source for the
Array#combination
method is written in C, so I don't really have the skill to alter it.

What I'm specifically trying to do is run a block for each element of the
array.combination
results, but I don't want to load up all the length-N combinations into memory first.

I've looked around for an implementation of
combination
that I can understand, but I'm having a difficult time.

Answer

"What I'm specifically trying to do is run a block for each element of the array.combination results, but I don't want to load up all the length-N combinations into memory first."

That is exactly what your code is doing. You are invoking the combination method without a block, which results in an Enumerator. Then you use its eachmethod. Only one combination is in memory at a time.