2010-03-24 5 views
0

Disons que j'ai deux objets: Utilisateur et Course.Convertir un tableau de hachages en tableau de structs?

class User 
    attr_accessor :first_name 
    attr_accessor :last_name 
end 

class Race 
    attr_accessor :course 
    attr_accessor :start_time 
    attr_accessor :end_time 
end 

Maintenant, disons que je crée un tableau de hachages comme ceci:

user_races = races.map{ |race| {:user => race.user, :race => race} } 

Comment puis convertir user_races dans un tableau de struct, en gardant à l'esprit que je veux être en mesure d'accéder à la attributs de l'utilisateur et de la course de l'élément struct? (L'élément clé est que je veux créer un nouvel objet via Struct afin que je puisse accéder aux attributs combinés de l'utilisateur et de la course.Par exemple, UserRace.name, UserRace.start_time.)

Répondre

2

Essayez ceci:

class User 
    attr_accessor :first_name 
    attr_accessor :last_name 
end 

class Race 
    attr_accessor :course 
    attr_accessor :start_time 
    attr_accessor :end_time 
end 

UserRace = Struct.new(:first_name, :last_name, :course, :start_time, :end_time) 

def get_user_race_info  
    user_races = races.map do |r| 
    UserRace.new(r.user.first_name, r.user.last_name, 
       r.course, r.start_time, r.end_time) 
    end 
end 

Testons maintenant le résultat:

user_races = get_user_race_info 
user_races[0].first_name 
user_races[0].end_time 
+0

Si j'essaie de mettre cela comme une méthode dans la classe d'utilisateur, comme def self.fastest_time_record_holders courses = Race.by_fastest_time UserRace = Struct.new (: prenom,: last_name,: cours,: START_TIME: end_time) user_races = races.map faire | r | UserRace.new (nom_utilisateur_utilisateur, nom_utilisateur.nom_utilisateur, r.course, temps_de_r.arrivée, heure_finale) fin fin Je reçois une erreur de constante dynamique. Qu'est-ce que je dois faire? – keruilin

+0

Vous ne pouvez pas redéfinir la structure dans votre méthode. Mettez la définition de la structure à l'extérieur du corps de la méthode. J'ai mis à jour ma réponse, jetez un oeil –

1

Créer une définition pour l'objet UserRace (en tant que Struct), alors faites simplement un tableau desdits objets.

UserRace = Struct.new(:user, :race) 

user_races = races.map { |race| UserRace.new(race.user, race) } 

# ... 

user_races.each do |user_race| 
    puts user_race.user 
    puts user_race.race 
end 
+0

La question semble un peu vague. Mais cela me semble juste. – Levi

+0

Oui, excuses si vague. L'élément clé est que je veux créer un nouvel objet via Struct afin que je puisse accéder aux attributs combinés de l'utilisateur et de la course. Par exemple, UserRace.name, UserRace.start_time. Avoir du sens? – keruilin

+0

+1 - C'est une solution élégante, mais je pense qu'elle ne répond pas à la vraie question, c'est-à-dire qu'elle ne convertit pas réellement un tableau de hachages en tableau de structures ... bien que cela résoudra ce problème particulier. – RubyDubee

0

Vous avez cette :::

user_races = races.map{ |race| {:user => race.user, :race => race} } 

Maintenant, créez un struct comme indiqué ci-dessous :

UserRace = Struct.new(:user, :race) 

Et puis ::

user_races.each do |user_race| 
    new_array << UserRace.new(user_race[:user],user_race[:race]) 
end 

ai pas testé le code ... devrait être bon ... ce dire?

EDIT: Ici j'ajoute les objets de UserRace à un new_array.

1

si votre hachage a tant d'attributs tels que les énumérer tous:

user_races = races.map{ |race| {:user => race.user, :race => race, :best_lap_time => 552.33, :total_race_time => 1586.11, :ambient_temperature => 26.3, :winning_position => 2, :number_of_competitors => 8, :price_of_tea_in_china => 0.38 } } # garbage to show a user_race hash with many attributes 

devient lourd (ou si vous pouvez ajouter d'autres attributs plus tard), vous pouvez utiliser l'opérateur * (« Splat »).

the splat operator converts an array into an argument list. afin que vous puissiez remplir la liste des arguments de Struct.new avec la liste des clés de votre hachage en faisant:

UserRace = Struct.new(*races.first.keys) 

bien sûr, cela suppose tous les hash dans votre tableau ont les mêmes touches (dans le même ordre). Une fois la structure définie, vous pouvez utiliser inject pour créer le tableau final des objets. (inject greatly simplifies converting many objects from one data type to another.)

user_races.inject([]) { |result, user_race| result << UserRace.new(*user_race.values) } 
Questions connexes