Comment analyser un hachage Ruby plat en un hachage imbriqué?
J'ai le hachage Ruby plat suivant:
{
"builder_rule_0_filter"=>"artist_name",
"builder_rule_0_operator"=>"contains",
"builder_rule_0_value_0"=>"New Found Glory",
"builder_rule_1_filter"=>"bpm",
"builder_rule_1_operator"=>"less",
"builder_rule_1_value_0"=>"150",
"builder_rule_2_filter"=>"days_ago",
"builder_rule_2_operator"=>"less",
"builder_rule_2_value_0"=>"40",
"builder_rule_3_filter"=>"release_date_start",
"builder_rule_3_operator"=>"between",
"builder_rule_3_value_0"=>"2019-01-01",
"builder_rule_3_value_1"=>"2019-12-31",
}
J'aimerais le convertir en un hachage imbriqué un peu plus organisé / utilisable:
{
"0"=>
{
"filter"=>"artist_name",
"operator"=>"contains",
"values"=>
{
"0"=>"New Found Glory"
}
},
"1"=>
{
"filter"=>"bpm",
"operator"=>"less",
"values"=>
{
"0"=>"150"
}
}
"2"=>
{
"filter"=>"days_ago",
"operator"=>"less",
"values"=>
{
"0"=>"40"
}
}
"3"=>
{
"filter"=>"release_date_start",
"operator"=>"between",
"values"=>
{
"0"=>"2019-01-01"
"1"=>"2019-12-31"
}
}
}
Alors, comment convertir un hachage plat (que j'obtiens à partir d'un formulaire) et le convertir pour qu'il soit imbriqué en fonction de ces noms de clés?
Vous pouvez d'abord diviser le hachage en plusieurs hachages en fonction de leur numéro de préfixe (n'hésitez pas à l'exécuter pour voir la valeur de retour)
groups = input.
group_by { |k,v| k.match(/builder_rule_(\d+)/)[1] }.
transform_values(&:to_h)
à ce stade, la création des objets internes est plus facile si vous utilisez simplement un codage en dur pour créer les key-valls:
result = groups.each_with_object({}) do |(prefix, hash), memo|
memo[prefix] = {
"filter" => hash["builder_rule_#{prefix}_filter"],
"operator" => hash["builder_rule_#{prefix}_operator"],
"values" => hash.select do |key, val|
key =~ /builder_rule_#{prefix}_value/
end.sort_by { |key, val| key }.map { |(key, val)| val }
}
end
Il peut être difficile de savoir ce que cela .sort_by { |key, val| key }.map { |(key, val)| val }
signifie. Je peux l'épeler:
hash.select { |key, val| key =~ /builder_rule_#{prefix}_value/ }
obtient les valeurs-clés qui vont être utilisées pour le tableau "values". Il renvoie un hachage..sort_by { |key, val| key }
transforme le hachage en un tableau de[key, val]
tuples, triés par clé. Ceci afin que les valeurs apparaissent dans le bon ordre..map { |(key, val)| val }
transforme le tableau imbriqué en un tableau à un seul niveau, en supprimant les clés
Vous pouvez également utiliser sort_by(&:first).map(&:second)
, bien que vous ayez besoin d'un soutien actif pour utiliserArray#second