1

我想找到数组中每个数组元素的交点并取交点。

输入是数组数组,例如“'list_arrays',如下面脚本中提到的”“过滤器”是需要对观察到的交叉点的总长度应用的限制输出预期为这样的数组“[[2 ,4]]"

list_arrays = [[1, 2, 3, 4], [2, 5, 6], [1, 5, 8], [8, 2, 4]]
filter = 2

first_element_array = Array.new
list_arrays.each_with_index do |each_array1, index1|        
 list_arrays.each_with_index do |each_array2, index2|
  unless index1 < index2
   intersection = each_array1 & each_array2
   if intersection.length == filter.to_i
    first_element_array.push(intersection)
   end
  end
 end
end
puts first_element_array

上述过程需要很长时间,因为我的数组数组太长(以百万行为单位)。我需要一种简单的 rubistic 方法来处理这个问题。有人对此有任何简单的想法吗?

4

1 回答 1

6

解密您的代码似乎您要求的是“如果该交集具有一定大小(示例中为 2),则返回集合的对组合之间的交集”。我会写(功能方法):

list_arrays = [[1, 2, 3, 4], [2, 5, 6], [1, 5, 8], [8, 2, 4]]
list_arrays.combination(2).map do |xs, ys|
  zs = xs & ys 
  zs.size == 2 ? zs : nil
end.compact
#=> [[2, 4]]

建议的优化:1)使用集合,2)使用自定义抽象Enumerable#map_compact(相当于map+compact但它会动态丢弃nils,自己编写)。3)过滤掉不满足谓词的子数组:

require 'set'
xss = list_arrays.select { |xs| xs.size >= 2 }.map(&:to_set)
xss.combination(2).map_compact do |xs, ys|
  zs = xs & ys 
  zs.size == 2 ? zs : nil
end
#=> [#<Set: {2, 4}>]
于 2013-02-28T14:54:12.847 回答