1
votes

Fusionner deux tableaux dans Ruby par clé unique

Comment puis-je fusionner deux tableaux avec l'unique key :

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

pour obtenir ce qui suit?

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]]
]


4 commentaires

Veuillez nous montrer ce que vous avez essayé.


Astuce: group_by semble utile ici


La logique de la question n'est pas claire. Que fait keyList ?


Quelles sont les règles de fusion de ces tableaux dans la structure finale?


4 Réponses :



5
votes

On ne sait pas pourquoi le tableau keyList est nécessaire.

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

h [k] pourrait être remplacé par h [k] si nécessaire pour le comportement souhaité.

Ce qui précède pourrait également être écrit comme suit.

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]]]]


3 commentaires

Cela ne répond pas à la partie «fusionner deux tableaux».


@AlekseiMatiushkin C'est la faute de l'OP. La question n'est pas claire.


@sawa Je ne blâme sûrement pas Cary. Toute la question était si mal formulée (et même mal formatée) que j'ai posté la réponse littéralement par pitié. Je fais juste remarquer cela.



4
votes
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]]]
# ]

4 commentaires

C'est la meilleure réponse ici jusqu'à présent.


@AlekseiMatiushkin Mais je pense qu'OP travaille avec ruby ​​ et transform_values ​​ est spécifique aux rails.


@ray Pas du tout depuis 2.4.0 .


@AlekseiMatiushkin mon mauvais, je vais jeter un oeil :)



0
votes

Même si cela n'apparaît pas dans le résultat attendu, je prendrais également en compte keyList , juste au cas où:

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", []]]

Pour se débarrasser sur ["d", []] , ajoutez simplement .reject {| e | e.last.empty? } .


0 commentaires