2017-09-21 1 views
0

J'ai le tableau suivant qui est en réalité une combinaison de deux tableaux. Mon objectif est que les 2 hachages avec employeeId de 898989 puissent être combinés et que je puisse ajouter leurs comptes ensemble et changer leur type en deux. J'ai essayé le code ci-dessous qui est proche de ce que je veux, mais je perds les autres valeurs de mes hachages. Existe-t-il un moyen facile de cartographier toutes les valeurs et de faire des manipulations comme l'ajout des comptes comme je le veux?Ruby combine un tableau de hachages avec la même clé et plusieurs valeurs

combined = [{"@rid"=>"#-2:1", "employeeId"=> "898989", "count"=>1, :type=>"wiki" }, 
     {"@rid"=>"#-2:3", "employeeId"=> "2423213", "count"=>7, :type=>"search"}, 
     {"@rid"=>"#-2:2", "employeeId"=> "555555", "count"=>2, :type=>"search"}, 
     {"@rid"=>"#-2:5", "employeeId"=> "898989", "count"=>2, :type=>"search"}, 
     {"@rid"=>"#-2:1", "employeeId"=> "5453454", "count"=>1, :type=>"search"}, 
     {"@rid"=>"#-2:4", "employeeId"=>"987654321", "count"=>1, :type=>"search"}] 

merged_array_hash = combined.group_by { |h1| h1["employeeId"] }.map do |k,v| 
    { "employeeId" => k, :types => v.map { |h2| h2[:type] }.join(", ") } 
end 

merged_array_hash finit par être:

[{employeeId: "898989",types: "wiki, search"}, 
{employeeId: "2423213",types: "search"}, 
{employeeId: "555555",types: "search"}, 
{employeeId: "5453454",types:"search"}, 
{employeeId: "987654321",types: "search"}] 

Ce que je cherche à obtenir:

[{employeeId: "898989",type: "both", count: 2}, 
{employeeId: "2423213",type: "search", count: 7}, 
{employeeId: "555555",type: "search", count: 2}, 
{employeeId: "5453454",type:"search", count: 1}, 
{employeeId: "987654321",type: "search", count: 1}] 
+0

Ce code ne fonctionne pas. Pouvez-vous expliquer ce que les variables 'wiki' et' search' sont censées contenir? – Zack

+1

Lorsque vous donnez un exemple, veuillez montrer le résultat souhaité sous la forme d'un objet Ruby. ("combined = wiki + search" ne répond pas à cette exigence.) De plus, il est utile d'assigner une variable à chaque objet d'entrée (ici il n'y en aurait qu'une, peut-être 'arr = [{" @arid "=> ... }, {...}] '). De cette façon, les lecteurs peuvent se référer à ces variables dans les réponses et les commentaires sans avoir à les définir, et tout le monde utilisera les mêmes noms de variables. –

+0

Je crois que cela ne vous dérange pas l'édition que j'ai faite. J'ai simplement reformaté afin que les lecteurs n'auraient pas à faire défiler horizontalement, et ajouté un nom de variable pour le tableau. –

Répondre

0

Pas beau, mais il va faire le travail:

combined.group_by { |h1| h1["employeeId"] }.map do |k,v| 
    types = v.map { |h2| h2[:type] } 
    count = v.sum { |x| x['count'] } 

    { employeeId: k, 
    types: (types.length == 1 ? types[0] : 'both'), 
    count: count } 

end 

=> [{:employeeId =>"898989", :types=>"both", :count=>3}, 
    {:employeeId =>"2423213", :types=>"search", :count=>7}, 
    {:employeeId =>"555555", :types=>"search", :count=>2}, 
    {:employeeId =>"5453454", :types=>"search", :count=>1}, 
    {:employeeId =>"987654321", :types=>"search", :count=>1}] 
+0

J'ai implémenté cette solution et ça semble faire l'affaire. Merci pour votre aide, je l'apprécie. –

0

Également pas belle, obtiendra aussi t il travail fait, potentiellement plus lisible

hash = {} 
combined.each do |h| 
    employeeId, count, type = h.values_at("employeeId", "count", :type) 
    if hash.include? employeeId 
    hash[employeeId][:count] += count 
    hash[employeeId][:type] = "both" #assumes duplicates can only occur if item is in both lists 
    else 
    hash[employeeId] = { :employeeId => employeeId, :type => type, :count => count } 
    end 
end 
hash.values 

Test:

[{:employeeId=>"898989", :type=>"both", :count=>3}, 
{:employeeId=>"2423213", :type=>"search", :count=>7}, 
{:employeeId=>"555555", :type=>"search", :count=>2}, 
{:employeeId=>"5453454", :type=>"search", :count=>1}, 
{:employeeId=>"987654321", :type=>"search", :count=>1}]