Объединить два массива в Ruby по уникальному ключу - PullRequest
0 голосов
/ 21 января 2019

Как объединить два массива с уникальным 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 голосов
/ 21 января 2019

Даже если он не отображается в ожидаемом результате, я бы также принял во внимание 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? }.

0 голосов
/ 21 января 2019

Непонятно, зачем нужен массив 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
0 голосов
/ 21 января 2019
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]]]
# ]
0 голосов
/ 21 января 2019

Использование 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]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...