J'ai un tableau de hachages comme suit:
details = [ {:name => "Alice", :age => 20}, {:name => "Ted", :age => 25}, {:name => "Poppy", :age => 33}, {:name => "Amy", :age => 20}, {:name => "Ted", :age => 90}, {:name => "Amy", :age => 22}, {:name => "Ted", :age => 23} ]
Je veux être en mesure de trier afin que je puisse ordonner en fonction du nombre de fois que les noms de chaque personne apparaissent. Par exemple, la sortie peut être:
"Ted, Ted, Ted, Amy, Amy, Alice, Poppy"
Quelqu'un peut-il vous aider? :)
Merci
4 Réponses :
Obtenez un hachage de comptage des noms, puis triez les nombres de noms:
details.each.with_object(Hash.new(0)) { |e, c| c[e[:name]] += 1 }. then { |c| details.sort_by { |e| -c[e[:name]] } }. map { |e| e[:name] }
... ou c [e [: name]] - = 1
avec {| e | c [e [: nom]]}
. Pour les lecteurs qui ne connaissent pas Object # then , il a fait ses débuts dans la v2.6.
cela retournera en fonction de l'occurrence de l'attribut de nom:
sorted_group_details.map{|d| d[1]}.flatten
par défaut, il renvoie l'ordre croissant. si vous voulez trier par le plus d'occurrence, ajoutez simplement reverse
sorted_group_details.reverse
et, si vous voulez renvoyer un objet aplatir à partir du tableau groupé:
sorted_group_details = details.group_by{|d| d[:name]}.sort_by{|key, val| val.count}
output_array = [] Hash[details.group_by{|data| data[:name]}.transform_values(&:count).sort_by{|k,v| v}.reverse].each{|key,value| value.times do output_array.push(key) end } output_array will have the results
b = details.map { |h| h[:name] } #=> ["Alice", "Ted", "Poppy", "Amy", "Ted", "Amy", "Ted"] c = b.group_by(&:itself) #=> {"Alice"=>["Alice"], "Ted"=>["Ted", "Ted", "Ted"], "Poppy"=>["Poppy"], # "Amy"=>["Amy", "Amy"]} d = c.values #=> [["Alice"], ["Ted", "Ted", "Ted"], ["Poppy"], ["Amy", "Amy"]] e = d.sort_by { |a| -a.size } #=> [["Ted", "Ted", "Ted"], ["Amy", "Amy"], ["Alice"], ["Poppy"]] e.flatten #=> ["Ted", "Ted", "Ted", "Amy", "Amy", "Alice", "Poppy"]
Avez-vous essayé quelque chose par vous-même?
Si vous ne voulez que les noms, il peut être plus facile de les extraire via
details.map {| h | h [: name]}
puis triez["Alice", "Ted", "Poppy", "Amy", "Ted", "Amy", "Ted"]
par le nombre d'occurrences. C'est fondamentalement la même tâche, mais travailler avec des objets plus simples (des chaînes au lieu de hachages contenant ces chaînes) facilite la compréhension.