Рекурсивно найти набор общих элементов из многомерного массива

У меня есть многомерный массив:

a=[[2,3,4],[1,3,4],[1,2],[1,2,3,4]]

Я должен сравнить все 4 подмассива и получить общие элементы. Затем взять 3 подмассива за раз и получить общие элементы. Затем взять 2 подмассива за раз и получить общие элементы в RUBY.


person shreyas    schedule 06.04.2010    source источник


Ответы (1)


Это должно работать в последних версиях 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
comment
@Mladen, Яблонович, это потрясающе элегантное решение. Можете ли вы немного обновить свой ответ, чтобы объяснить немного больше о том, как это работает. В частности, что такое &:& и как он работает с Enumerable#inject? - person maček; 06.04.2010