通过唯一键在Ruby中合并两个数组

时间:2019-01-21 08:25:53

标签: arrays ruby

如何将两个数组与唯一的key合并:

keyList = ["a", "b", "c", "d"]

keyValueList = [
  ["a", [1, 2, 3]],
  ["a", [4, 5, 6]],
  ["b", [5, "a", 3]],
  ["b", ["test", 4, 3]],
  ["c", [1, "number", 110]]
]

获得以下内容?

[
  ["a", [[1, 2, 3], [4, 5, 6]]],
  ["b", [[5, "a", 3], ["test", 4, 3]]],
  ["c", [[1, "number", 110]]]
]

4 个答案:

答案 0 :(得分:7)

使用Enumerable#group_by

keyValueList.
  map(&:flatten).
  group_by(&:shift).
  select { |k, _| keyList.include?(k) }.
  to_a
#⇒ [["a", [[1, 2, 3], [4, 5, 6]]],
#   ["b", [[5, "a", 3], ["test", 4, 3]]],
#   ["c", [[1, "number", 110]]]

答案 1 :(得分:5)

尚不清楚为什么需要数组keyList

keyValueList.each_with_object(Hash.new {|h,k| h[k]=[]}) do |(k,arr),h|
  h[k] << arr
end.to_a
  #=> [["a", [[1, 2, 3], [4, 5, 6]]],
  #    ["b", [[5, "a", 3], ["test", 4, 3]]],
  #    ["c", [[1, "number", 110]]]]
如果需要,

h[k] << arr可以更改为h[k] << arr if keyList.include?(k)

以上内容也可以写成如下。

keyValueList.each_with_object({}) do |(k,arr),h|
  (h[k] ||= []) << arr
end.to_a

答案 2 :(得分:4)

keyValueList
.group_by(&:first)
.transform_values{|a| a.map(&:last)}
.to_a
# => [
#  ["a", [[1, 2, 3], [4, 5, 6]]],
#  ["b", [[5, "a", 3], ["test", 4, 3]]],
#  ["c", [[1, "number", 110]]]
# ]

答案 3 :(得分:0)

即使它没有出现在预期的结果中,我也会考虑keyList,以防万一,所以:

keyList
.each_with_object({}) { |k, h| h[k] = keyValueList.select { |x, y| x == k }.map(&:last) }
.to_a

#=> [["a", [[1, 2, 3], [4, 5, 6]]], ["b", [[5, "a", 3], ["test", 4, 3]]], ["c", [[1, "number", 110]]], ["d", []]]

要摆脱["d", []],只需附加.reject{ |e| e.last.empty? }