Это должно работать в последних версиях Ruby:
a.length.downto(1).map{|i| a.combination(i).map{|sub| sub.inject(&:&)}}
#=> [[[]], [[], [3, 4], [2], [1]], [[3, 4], [2], [2, 3, 4], [1], [1, 3, 4], [1, 2]], [[2, 3, 4], [1, 3, 4], [1, 2], [1, 2, 3, 4]]]
Вот связанный вопрос с аналогичным решением. «Хитрость» заключается в методе Array#&
, который вычисляет пересечение (как операцию множества) двух массивов. Это ассоциативная операция, поэтому мы можем применять ее к каждому подмассиву по очереди, сохраняя накопленный результат , поэтому inject
идеально подходит для этого. Короче говоря, array.inject(&:&)
приведет к наибольшему общему подмножеству элементов в каждом члене array
. &:&
— это просто сокращение Ruby для создания Proc
из метода с именем &
и отправки его в виде блока в inject
вместо записи:
array.inject{|a,e| a & e}
person
Mladen Jablanović
schedule
06.04.2010