Массив хэшей выдвинуть в другой массив - PullRequest
0 голосов
/ 25 мая 2018

У меня есть массив, содержащий хэши, я хочу отфильтровать несколько параметров из хэша и вставить отфильтрованные данные в другой массив, но у меня ничего не получилось. Ниже приведены примеры данных, которые я использовал

a = Array.new
a = [
  {"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"},
  {"name"=>"name2", "age"=>"26", "sex"=> "M", "city"=>"Banglore"}
]
line_item = Array.new
hash_data = {}

a.each do |datas|
  hash_data[:name] = datas["name"]
  hash_data[:age] = datas["age"]
  line_item << hash_data
end

Я получаю этот результат:

[
  {:name=>"name2", :age=>"26"},
  {:name=>"name2", :age=>"26"}
]

Но я ожидаю этого:

[
  {:name=>"hello", :age=>"12"},
  {:name=>"name2", :age=>"26"}
]

Кто-нибудь, пожалуйста, помогите разобраться, Заранее спасибо

Ответы [ 6 ]

0 голосов
/ 25 мая 2018

Определение хеша вне цикла означает, что вы продолжаете добавлять один и тот же хеш-объект снова (перезаписывая его предыдущие значения).Вместо этого создайте новый хэш в цикле:

line_items = []
a.each do |datas|
  hash_data = {}
  hash_data[:name] = datas["name"]
  hash_data[:age] = datas["age"]
  line_items << hash_data
end

Код выглядит немного недиоматичным.Давайте сделаем рефакторинг.

Мы можем установить ключи прямо внутри хеш-литерала:

line_items = []
a.each do |datas|
  hash_data = { name: datas["name"], age: datas["age"] }
  line_items << hash_data
end

Мы можем избавиться от переменной hash_data:

line_items = []
a.each do |datas|
  line_items << { name: datas["name"], age: datas["age"] }
end

И мы можем использовать map для непосредственного преобразования массива:

line_items = a.map { |h| { name: h["name"], age: h["age"] } }
#=> [{:name=>"hello", :age=>"12"}, {:name=>"name2", :age=>"26"}]
0 голосов
/ 25 мая 2018

Вы можете получить ожидаемый результат с помощью комбинации map и slice

a = [
  {"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"},
  {"name"=>"name2", "age"=>"26", "sex"=> "M", "city"=>"Banglore"}
]

a.map{ |e| e.slice("name", "age") }
#=> [{"name"=>"hello", "age"=>"12"}, {"name"=>"name2", "age"=>"26"}]
  • map: возврат Array содержит значения, возвращаемые блоком
  • slice: возвращает Hash, включая только указанные ключи
0 голосов
/ 25 мая 2018

Я думаю, что многие слишком усложняют это.

Вы можете добиться этого, используя следующее:

a.map { |hash| hash.select { |key, _value| key == 'name' || key == 'age' } }

Если вы хотите вернуть массив, вы почти всегда должны бытьс помощью map и select просто выбираются пары ключ-значение, соответствующие критериям.

Если вы настроены на использование символов в качестве ключей, вы можете позвонить symbolize_keys в результате.

Я расширю код, чтобы он был немного более читабельным, но один из приведенных выше символов работает отлично:

a.map do |hash| 
  hash.select do |key, _value| 
    key == 'name' || key == 'age'
  end
end
0 голосов
/ 25 мая 2018

Если вы хотите для всех ключей, вы можете сделать это

array     = [{"name"=>"hello", "age"=>"12", "sex"=> "M", "city"=>"Chennai"}, {"name"=>"name2", "age"=>"26""sex"=> "M", "city"=>"Banglore"}]

new_array = array.map{|b| b.inject({}){|array_obj,(k,v)| array_obj[k.to_sym] = v; array_obj}}

Ссылка: Ввести

Happy Coding

0 голосов
/ 25 мая 2018

В вашем цикле вы пополняете line_item на hash_data дважды.Это тот же объект, однако.Вы можете исправить это, используя .dup.

a.each do |datas|
  hash_data[:name]=datas["name"]
  hash_data[:age]=datas["age"]
  line_item << hash_data.dup # <- here
end

irb(main):044:0> line_item
=> [{:name=>"hello", :age=>"12"}, {:name=>"name2", :age=>"26"}]

Редактировать: Я предпочитаю предложение Радо переместить ваше определение hash_data внутри цикла поверх .dup.Это решает проблему больше, чем лечит симптом.

0 голосов
/ 25 мая 2018

В первой строке hash_data[:name]=datas["name"] вы устанавливаете ключ хеша.Вот почему, когда цикл повторяется снова, он переопределяет значение и после этого отправляет новый результат в хеш.

Одно из решений с повторным использованием этого кода - просто поставить hash_data = {} в первой строке вашегопетля.Таким образом, у вас будет совершенно новый хеш для работы на каждой итерации.

Также я бы порекомендовал вам прочитать документы по хеш-модулю.Вы найдете более полезные методы там.

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