Let's say I have two objects: User and Race.
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
Now let's say I create an array of hashes like this:
user_races = races.map{ |race| {:user => race.user, :race => race} }
How do I then convert user_races into an array of structs, keeping in mind that I want to be able to access the attributes of both user and race fro开发者_StackOverflowm the struct element? (The key thing is I want to create a new object via Struct so that I can access the combined attributes of User and Race. For example, UserRace.name, UserRace.start_time.)
Try this:
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
Now let's test the result:
user_races = get_user_race_info
user_races[0].first_name
user_races[0].end_time
Create a definition for the UserRace object (as a Struct), then just make an array of said objects.
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
if your hash has so many attributes such that listing them all:
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
becomes cumbersome (or if you may be adding more attributes later), you can use the *
("splat") operator.
the splat operator converts an array into an argument list. so you can populate Struct.new's argument list with the list of keys in your hash by doing:
UserRace = Struct.new(*races.first.keys)
of course, this assumes all hashes in your array have the same keys (in the same order).
once you have your struct defined, you can use inject
to build the final array of objects. (inject greatly simplifies converting many objects from one data type to another.)
user_races.inject([]) { |result, user_race| result << UserRace.new(*user_race.values) }
You have this :::
user_races = races.map{ |race| {:user => race.user, :race => race} }
Now create a Struct as shown below :
UserRace = Struct.new(:user, :race)
And then ::
user_races.each do |user_race|
new_array << UserRace.new(user_race[:user],user_race[:race])
end
Haven't tested the code... should be fine... what say?
EDIT: Here I am adding the objects of UserRace to a new_array.
精彩评论