Как перебрать вложенную Ruby га sh, чтобы добавить новую пару ключ / значение на основе существующих данных ключ / значение? - PullRequest
1 голос
/ 18 февраля 2020
  1. У меня есть вложенный ха sh данных:

    munsters = {
      "Herman" => { "age" => 32, "gender" => "male" },
      "Lily" => { "age" => 30, "gender" => "female" },
      "Grandpa" => { "age" => 402, "gender" => "male" },
      "Eddie" => { "age" => 10, "gender" => "male" },
      "Marilyn" => { "age" => 23, "gender" => "female"}
    }
    
  2. Я хочу, чтобы l oop через га sh для каждого члена и найдите его возраст во вложенном ха sh.

  3. Для каждого члена я хочу добавить новую пару ключ / значение в существующий вложенный га sh с именем " age_group ".

  4. Значение" age_group "каждого участника будет зависеть от его возраста. Например, если возраст старше 65 лет, я хочу, чтобы их возрастная группа читалась как «сеньор», et c.

Проблемы, с которыми я сталкиваюсь:

Я не понимаю, как получить доступ к паре «возраст» key_value вложенного ха sh, когда первый ключ различен для каждого члена семьи. Это значит, что я не могу сделать что-то вроде munsters["age"], потому что это возвращает ноль (при условии, что «возраст» является вложенным).

Если бы у меня был простой (не вложенный) ха sh, это довольно просто. Пример не вложенного ха sh:

ages = { "Herman" => 32, "Lily" => 30, "Grandpa" => 402, "Eddie" => 10 }

Я бы тогда, вероятно, l oop, хотя бы так:

age_group = {}

ages.each do |k, v|
  if v >= 65
    puts "#{k}'s age of #{v} makes them a senior!"
    age_group.merge!("age_group": "senior")
  elsif v > 17 && v < 65
    puts "#{k}'s age of #{v} makes them an adult"
    age_group.merge!("age_group": "adult")
  else
    puts "#{k}'s age of #{v} makes them a kid."
    age_group.merge!("age_group": "kid")
  end
end

Для вложенного ха sh, I Я могу получить доступ ко всему вложенному ха sh следующим образом:

munsters.each do |k, v|
  v.each do |k2, v2|
    p "k2 is #{k2} and v2 is #{v2}"
  end
end

Но это все равно только возвращает весь вложенный ха sh на консоль, а не только возраст:

k2 is age and v2 is 32
k2 is gender and v2 is male

Ответы [ 4 ]

2 голосов
/ 18 февраля 2020

В дополнение к ответу @MurifoX вы можете использовать #transform_values

ages.transform_values do |value|
  if value["age"] >= 65
    value["age_group"] = "senior"
  elsif value["age"] > 17 && value["age"] < 65
    value["age_group"] = "adult"
  else
    value["age_group"] = "kid"
  end
end
1 голос
/ 19 февраля 2020
def age_group(age)
  case age
  when 0..17 then "kid"
  when 18..64 then "adult"
  else "senior"
  end
end

munsters.each_value { |h| h["age_group"] = age_group(h["age"]) }
  #=> {"Herman" =>{"age"=>32,  "gender"=>"male",   "age_group"=>"adult"},
  #    "Lily"   =>{"age"=>30,  "gender"=>"female", "age_group"=>"adult"},
  #    "Grandpa"=>{"age"=>402, "gender"=>"male",   "age_group"=>"senior"}, 
  #    "Eddie"  =>{"age"=>10,  "gender"=>"male",   "age_group"=>"kid"}, 
  #    "Marilyn"=>{"age"=>23,  "gender"=>"female", "age_group"=>"adult"}}

Это возвращаемое значение является новым значением munsters.

1 голос
/ 18 февраля 2020

v - это тоже ха sh. Таким образом, вы можете сделать это следующим образом:

ages.each do |k, v|
  if v["age"] > 60
    ages[k]["age_group"] = "adult"
  else
    ages[k]["age_group"] = "kid"
  end
end

Вы добавляете ключ age_group со строковым значением к позиции k вашего возраста ha sh.

0 голосов
/ 19 февраля 2020

Проблема с вашей текущей попыткой состоит в том, что вы пытаетесь что-то сделать для каждой пары ключ / значение каждой munster. Однако вас интересуют только "age" и "age_group". Таким образом, нет необходимости повторять пары ключ / значение munster. Вместо этого работайте непосредственно с munster.

Другие примеры, в основном, демонстрируют мутирующее решение, поэтому позвольте мне предложить не мутирующую альтернативу (это означает, что munsters не меняется). Я также удалил заявление if , чтобы предоставить альтернативную перспективу.

threshholds = { "kid" => 0, "adult" => 18, "senior" => 65 }

age_groups = threshholds.each_key.sort_by(&threshholds)
new_munsters = munsters.transform_values do |munster|
  age_group = age_groups
    .take_while { |age_group| munster["age"] > threshholds[age_group] }
    .last

  munster.merge("age_group" => age_group)
end
#=> {
#   "Herman"=>{"age"=>32, "gender"=>"male", "age_group"=>"adult"},
#   "Lily"=>{"age"=>30, "gender"=>"female", "age_group"=>"adult"},
#   "Grandpa"=>{"age"=>402, "gender"=>"male", "age_group"=>"senior"},
#   "Eddie"=>{"age"=>10, "gender"=>"male", "age_group"=>"kid"},
#   "Marilyn"=>{"age"=>23, "gender"=>"female", "age_group"=>"adult"}
# }

Это решение использует transform_values для создания новой версии munsters, содержащий новые обновленные версии munster (созданные с merge).

...