基于一列合并2个阵列

时间:2013-06-26 14:58:36

标签: ruby arrays

我有两个数组:

a = [[1234,1],[2134,0],[4321,0],[2221,3]]
b = [[2134,1],[4321,3]]

我想基于a的第一个元素合并它们,以获得以下结果:

c = [[1234,1],[2134,1],[4321,3],[2221,3]]

如果第一个元素匹配,我想用a中的值替换b中的0。第一个元素在a和b中是唯一的。

我该怎么做?

提前致谢,

5 个答案:

答案 0 :(得分:2)

Hash#merge功能允许您指定一个块来定义如何处理这些值。

a = [[1234,1],[2134,0],[4321,0],[2221,3]]
b = [[2134,1],[4321,3]]
c = Hash[a].merge(Hash[b]) { |key, old, new| old+new }.to_a
# => [[1234, 1], [2134, 1], [4321, 3], [2221, 3]]

请参阅Hash#merge documentation

在这种情况下,我通过构建值的总和来完成合并。您可能希望选择最大值或其他适合您的策略。

免责声明:如果a(或b)包含具有相同第一个值的数组,则此方法不起作用。示例[[1, 1], [1, 4], [2, 8]]。如果发生这种情况,您的问题中没有说明。

答案 1 :(得分:1)

鉴于

a = [[1234,1],[2134,0],[4321,0],[2221,3]]

b = [[2134,1],[4321,3]]

您可以将这些数组转换为哈希值,执行合并,然后再将结果转换为数组。

Hash[a].merge(Hash[b]).to_a
#=> [[1234, 1], [2134, 1], [4321, 3], [2221, 3]]

答案 2 :(得分:1)

这是一种可能性:

a = [[1234,1],[2134,0],[4321,0],[2221,3]]
b = [[2134,1],[4321,3]]

a.zip(b).flatten(1).uniq(&:first)
# => [[1234, 1], [2134, 1], [4321, 3], [2221, 3]]

答案 3 :(得分:0)

[*a, *b].group_by(&:first).map{|k, v| [k, v.map(&:last).inject(:+)]}

答案 4 :(得分:0)

只需反转数组并调用唯一:

(b + a).uniq(&:first)

这是有效的,因为Array#+Array#concat的非变异版本。它将创建一个新的有序数组。无论哪个数组是第一个,都将优先于输出。调用uniq时,它将按顺序枚举数组,允许您只获取第一列的第一个实例。

您可以为n数组执行此操作:

[b,d,c,a].reduce(&:+).uniq(&:first)