Ruby 如何优雅的合并两个 List of hashs ?

lithium4010 · 2015年07月06日 · 最后由 cicholgricenchos 回复于 2015年07月07日 · 3093 次阅读

例如

list_1 = [{k: 1, v: "a"}, {k: 2, v: "b"}, {k:3, v:"c"}]
list_2 = [{k: 1, v: "x"}, {k: 4, v: "d"}]

merge(list_1, list_2, :k) 
# => [{k: 1, v: "x"}, {k: 2, v: "b"}, {k:3, v:"c"}, {k:4, v: "d"}]

其中的每个 hash 都以 hash[:k] 的值作为 key 来匹配

我现在的做法是

def merge(list_1, list_2, key)
  parse_to_hash = ->(list) { Hash[list.map { |o| [o[key], o] }] } 
  list_1_hash = parse_to_hash.(list_1)
  list_2_hash = parse_to_hash.(list_2)
  list_1_hash.merge(list_2_hash).values
end

如何实现这个 merge 更好?

从你的数据来看,可以把 list_1 转成 {1 => "a", 2 => "b", 3 => "c"} 把 list2 转成 {1 => "x", 4 => "d"} 然后用 2 个 hash merge 不就可以了吗?

转成 hash 可以用 Hash[l1.map(&:values).map(&:to_a)] 然而并不好看。 至于你这需求,我觉得改变一下数据结构效率会更高。 匹配:k 的话,总还是要用到 Hash 来去重的。

直接连接两个数组,然后用 Array#uniq,带一个代码块{|x| x[:k]}

不过这样是用顺序上左边的来 uniq,那连接的时候反着连就好了

写出来就是

def merge(l1,l2,key)
  result = l2 + l1
  result.uniq{|x| x[key]}
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号