0
votes

Tri d'un tableau Ruby de hachages en fonction du nombre de fois où une valeur apparaît

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


2 commentaires

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.


4 Réponses :


5
votes

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


1 commentaires

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



0
votes

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}


0 commentaires

0
votes
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

0 commentaires

0
votes
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"] 

0 commentaires