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

У меня есть следующий хэш

{"goes_by"=>[nil, ""], "middle_name"=>[nil, ""], "suffix"=>[nil, ""], "jersey"=>["8", "8A"]}

Я пытаюсь написать заявление, чтобы отклонить любые элементы, которые имеют вложенный массив с nil & "". Поэтому я написал следующую команду, чтобы попытаться выполнить это, но она возвращает nil, как будто в хеше не было никаких изменений...

Player.find(286).audits.first.audited_changes.reject! {|x| x[1][0].blank? && x[1][1].blank? }
         => nil 

но когда я распечатываю результаты, условие выполняется для трех элементов. Что мне здесь не хватает?

Player.find(286).audits.first.audited_changes.each {|x| puts x[1][0].blank? && x[1][1].blank? }

    true
    true
    true
    false

     => {"goes_by"=>[nil, ""], "middle_name"=>[nil, ""], "suffix"=>[nil, ""], "jersey"=>["8", "8A"]} 

person daveomcd    schedule 09.05.2015    source источник
comment
Создает ли #audited_changes хэш или обращается к переменной экземпляра?   -  person aerook    schedule 09.05.2015
comment
переменная экземпляра, насколько я понимаю, она хранится как часть записи. Если это поможет, это часть жемчужины audited.   -  person daveomcd    schedule 09.05.2015
comment
Итак, #reject! удалит только элементы из переменной экземпляра; он не будет делать никаких обновлений в базе данных. Вы обращаетесь к базе данных, чтобы убедиться, что операция сработала, которая возвращает новый объект ruby ​​со свежими значениями из базы данных. Попробуйте сохранить экземпляр игрока и сохранить его после отклонения: player = Player.find(286); player.audits.first.audited_changes.reject! { #... }; player.audits.first.save ;   -  person aerook    schedule 09.05.2015
comment
если {:goes_by=>[nil, ""], :middle_name=>[nil, ""], :suffix=>[nil, ""], :jersey=>["8", "8A"]} это ваш хэш, то hash.values.reject!{|x| x[0].nil? && x[1].empty?} должен работать на вас   -  person Sonalkumar sute    schedule 09.05.2015


Ответы (2)


прежде всего, когда вы вызываете reject! для хеша, помните, что ваш блок должен принимать два параметра, а не один. В вашем случае параметр x всегда является ключом вашего хэша, поэтому соответственно: go_by, middle_name, suffix,

поэтому блок должен выглядеть так:

.reject! { |key, array| array.all? { |array_item| array_item.blank? } }

person djaszczurowski    schedule 09.05.2015
comment
Если #reject! вызывается с блоком, который принимает один аргумент, каждая пара ключ/значение выдается в виде массива из 2 элементов. - person aerook; 09.05.2015
comment
Это сработало хорошо и улучшило мой уродливый код, спасибо! - person daveomcd; 09.05.2015

Помните, что вы используете reject! с хэш

{ "goes_by"=>[nil, ""],
  "middle_name"=>[nil, ""], 
  "suffix"=>[nil, ""],
  "jersey"=>["8", "8A"]
}.reject! {|key, value| value.all?(&:blank?) }]

Это вернет => {"Джерси" => ["8", "8A"]}

person cristian    schedule 09.05.2015