两个二维阵列在一个维度上的交点

时间:2014-03-11 10:36:17

标签: ruby arrays

我是Ruby新手。我有一个以下形式的二维数组(它可能是一个散列条目数组(键,值对)作为函数的参数,而不是像我在这里显示的那样初始化):

a = [[:"49e8cfb", 1],
[:"4b5a73dc", 1],
[:"4c1e65c4", 1],
[:"4cb4c06f", 1],
[:"4cc0ac3c", 5],
[:"4d8ee865", 21]]

我有另一个类似的数组(比如b)。我想基于第一列(字符串值)找到两个数组的交集。例如,如果

b = [[:"49e8cfb", 2],
[:"4b5a73dc", 78],
[:"4c1e65c4", 4],
[:"4cb4c06f", 3],
[:"4cc0ac3c", 52]]

然后交叉点应为

[:"49e8cfb", :"4b5a73dc", :"4c1e65c4", :"4cb4c06f", :"4cc0ac3c"]

3 个答案:

答案 0 :(得分:3)

使用Array#&执行以下操作:

a.map(&:first) & b.map(&:first)
  • a.map(&:first)你会给你一个来自a内部数据的所有第一个条目的数组。

  • b.map(&:first)会像我刚才所说的一样。

  • 然后对&a.map(&:first)返回的2个结果数组使用b.map(&:first)

答案 1 :(得分:3)

试试这个

a.group_by(&:first).keys & b.group_by(&:first).keys
=> [:"49e8cfb", :"4b5a73dc", :"4c1e65c4", :"4cb4c06f", :"4cc0ac3c"]

要求'基准'

Benchmark.bm do |x|
  x.report { a.group_by(&:first).keys & b.group_by(&:first).keys }
  x.report { a.map(&:first) & b.map(&:first) }
  x.report { a.collect(&:first) & b.collect(&:first) }
end

    user      system      total        real
  0.000000   0.000000   0.000000   (  0.000029)
  0.000000   0.000000   0.000000   (  0.000015)
  0.000000   0.000000   0.000000   (  0.000012)

因此使用a.collect(&:first) & b.collect(&:first)是最快的。

答案 2 :(得分:1)

你也可以试试这个

Hash[a].keys & Hash[b].keys
#=> [:"49e8cfb", :"4b5a73dc", :"4c1e65c4", :"4cb4c06f", :"4cc0ac3c"]

这会将两个对象转换为Hash,并仅返回两个哈希中存在的键。但collect是最快的,因为@AlokAnand指出。