Как сравнить массивы внутри массива друг с другом в ruby?

[ 1, 1, 3, 5 ] & [ 1, 2, 3 ]                 #=> [ 1, 3 ]
[ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ]   #=> [ 'a', 'b' ]

Мне нужно пересечение каждого массива со всеми другими массивами в массиве.

Таким образом, массив может выглядеть как ->

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

Результат должен выглядеть как ->

 a = [[3],[3,4,5][4,5]]

Какие-либо предложения?

2 ответа

Посмотрите на метод комбинирования.

a = [[1, 2, 3], [3, 4, 5], [4, 5, 6],[1,"a","b"]]

p a.combination(2).map{|x,y| x & y } #=> [[3], [], [1], [4, 5], [], []]

И если вы не хотите, чтобы там были пустые массивы:

p a.combination(2).map{|x,y| x & y }.reject(&:empty?) #=> [[3], [1], [4, 5]]

Изменить: После просмотра некоторых примеров, что ОП на самом деле хочет, вот как я бы достиг желаемого результата:

original = [[1, 2, 3], [3, 4, 5], [4, 5, 6]] 

def intersect_with_rest(array)
  array.size.times.map do
    first, *rest = array
    array.rotate!
    first & rest.flatten
  end
end

p intersect_with_rest(original) #=> [[3], [3, 4, 5], [4, 5]]
p original #=> [[1, 2, 3], [3, 4, 5], [4, 5, 6]]

Или же:

original = [[1, 2, 3], [3, 4, 5], [4, 5, 6]] 

result = original.map.with_index do |x,i|
  x & (original[0...i]+original[1+i..-1]).flatten
end

p result #=> [[3], [3, 4, 5], [4, 5]]

Да, наконец-то я нашел решение. Может быть, есть более простой способ, но это работает для меня сейчас..

c = [[1,2,3],[3,4,5],[4,5,6]]
results = [];c.length.times.each {|e| results.push c.rotate(e).combination(2).map {|x, y| x & y}}
results.map{|x, y| y + x}

=> [[3], [3, 4, 5], [4, 5]] 

Спасибо @hirolau за подсказку. С наилучшими пожеланиями

Другие вопросы по тегам