Преобразовать массив хешей в массив структур? - PullRequest
0 голосов
/ 24 марта 2010

Допустим, у меня есть два объекта: Пользователь и Гонка.

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

Теперь, допустим, я создал массив хэшей, например:

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

Как мне затем преобразовать user_races в массив структур, помня о том, что я хочу иметь возможность доступа к атрибутам пользователя и расы из элемента struct? (Главное, я хочу создать новый объект через Struct, чтобы я мог получить доступ к объединенным атрибутам User и Race. Например, UserRace.name, UserRace.start_time.)

Ответы [ 4 ]

2 голосов
/ 24 марта 2010

Попробуйте это:

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

Теперь давайте проверим результат:

user_races = get_user_race_info
user_races[0].first_name
user_races[0].end_time
1 голос
/ 27 июня 2012

, если ваш хэш имеет так много атрибутов, что перечисляет их все:

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

становится громоздким (или, если вы позже добавите больше атрибутов), вы можете использовать оператор * ("splat").

оператор splat преобразует массив в список аргументов. так что вы можете заполнить список аргументов Struct.new списком ключей в вашем хэше, выполнив:

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

конечно, это предполагает, что все хэши в вашем массиве имеют одинаковые ключи (в одинаковом порядке).

Как только вы определили свою структуру, вы можете использовать inject для построения окончательного массива объектов. ( Внедрение значительно упрощает преобразование многих объектов из одного типа данных в другой .)

user_races.inject([]) { |result, user_race| result << UserRace.new(*user_race.values) }
1 голос
/ 24 марта 2010

Создайте определение для объекта UserRace (как Struct ), а затем просто создайте массив из указанных объектов.

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 голосов
/ 24 марта 2010

У вас есть это :::

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

Теперь создайте Структуру, как показано ниже:

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

А потом ::

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

Не проверял код ... должно быть в порядке ... что сказать?

РЕДАКТИРОВАТЬ: Здесь я добавляю объекты UserRace к new_array.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...