2010-12-11 6 views
0

J'ai un tableau qui contient des dates et des valeurs. Un exemple de la façon dont il pourrait ressembler:Ruby façon de boucler et de vérifier les valeurs suivantes les uns par rapport aux autres

[ 
    {'1/1/2010' => 'aa'}, 
    {'1/1/2010' => 'bb'}, 
    {'1/2/2010' => 'cc'}, 
    {'1/2/2010' => 'dd'}, 
    {'1/3/2010' => 'ee'} 
] 

Notez que certaines des dates se répètent. J'essaye de produire ceci dans un format de tableau et je veux seulement montrer des dates uniques. Donc je fais une boucle avec le code suivant pour obtenir la sortie désirée.

prev_date = nil 
@reading_schedule.reading_plans.each do |plan| 
    use_date = nil 
    if plan.assigned_date != prev_date 
    use_date = plan.assigned_date 
    end 
    prev_date = plan.assigned_date 
    plan.assigned_date = use_date 
end 

Le tableau résultant sera alors ressembler à quelque chose comme ça

1/1/2010 aa 
     bb 
1/2/2010 cc 
     dd 
1/3/2010 ee 

Ce beau travail, mais je suis nouveau à ruby ​​et je me demandais s'il y avait une meilleure façon de le faire.

+0

Je voudrais voir le code utilisé pour générer les données d'exemple. Ce code pourrait probablement être changé pour le rendre plus facile d'obtenir le format désiré. Le tableau de hachages avec des paires clé/valeur unique n'est pas trop commun. –

+0

Les données sont dans ce format car elles correspondent à mon modèle. Mon instance de modèle a une date et un champ de type chaîne. – Lan

Répondre

2

Enumerable.group_by est un bon point de départ:

require 'pp' 

asdf = [ 
    {'1/1/2010' => 'aa'}, 
    {'1/1/2010' => 'bb'}, 
    {'1/2/2010' => 'cc'}, 
    {'1/2/2010' => 'dd'}, 
    {'1/3/2010' => 'ee'} 
] 

pp asdf.group_by { |n| n.keys.first }.map{ |a,b| { a => b.map { |c| c.to_a.last.last } } } 
# >> [{"1/1/2010"=>["aa", "bb"]}, {"1/2/2010"=>["cc", "dd"]}, {"1/3/2010"=>["ee"]}] 

Ce qui devrait être une structure de données que vous pouvez plier à votre volonté.

+0

Oooh, je ne connaissais pas Enumerable # group_by, vraiment cool. – Jacob

+0

Beaucoup de gens ne le font pas. Il y a des méthodes très intéressantes cachées dans les bibliothèques Core. –

1

Ceci est totalement un travail pour un hachage.

Créez un hachage et utilisez la date comme hashkey et un tableau vide comme hashvalue.

accumulera ensuite les valeurs du tableau d'origine dans le tableau de valeur de hachage

+1

Un hachage est très efficace ... vous pouvez également regarder dans Enumerable # group_by - vérifiez-le dans irb pour voir si vous obtenez les résultats que vous voulez. –

2

Je ne sais pas comme si il est préférable, mais vous pouvez regrouper les valeurs par date en utilisant (par exemple) Enumerable#reduce (nécessite Ruby> = 1.8. 7, avant cela, vous avez Enumerable#inject).

arr.reduce({}) { |memo, obj| 
    obj.each_pair { |key, value| 
    memo[key] = [] if ! memo.has_key?(key); 
    memo[key] << value 
    } 
    memo 
}.sort 

=> [["1/1/2010", ["aa", "bb"]], ["1/2/2010", ["cc", "dd"]], ["1/3/2010", ["ee"]]] 

Vous pouvez également utiliser Array#each pour obtenir un effet similaire.

Questions connexes