2013-02-27 2 views
1

создать хэш, который имеет много ключей, и я хочу, чтобы опустить ключи, которые имеют nil значения:опуская пустые значения при создании хэша

h = { 
    :key0 => val0, 
    :key1 => val1, # I want to include this key only if val1 is not nil 
    :key2 => val2 
} 

являются ли какими-либо приятными способами сделать это, кроме

if val1 
    h = { 
    :key0 => val0, 
    :key1 => val1, 
    :key2 => val2 
    } 
else 
    h = { 
    :key0 => val0, 
    :key2 => val2 
    } 
end 

что-то вдоль линий

h = { 
    :key0 => val0, 
    :key1 => val1 if val1, # gives an error 
    :key2 => val2 
} 

EDIT: спасибо за ответы до сих пор, повторно полезно. Есть ли способ определить хеш-литерал без необходимости его обрабатывать?

+0

Заканчивать этот вопрос, неправильно закрыт (IMO) на основе фразировки. Это тот же вопрос с несколькими хорошими ответами ... http: //stackoverflow.com/questions/14175958/conditional-inclusion-of-a-key-value-pair-in-a-hash – danh

ответ

4

Вы можете попробовать Hash#keep_if метод. Метод удаляет каждую пару ключ-значение из hsh, для которого блок оценивается как false.

h = { :key0 => 'val0',:key1 => nil,:key2 => 'val2',:key4 =>nil} 


h.keep_if {|key,value| !value.nil?} 

{: key0 => "val0",: key2 => "значение2"}

0

Метод «delete_if» может удалить определенные элементы, уступив блоку. Если этот блок возвращает true для элемента, этот элемент будет удален. Ваш код должен тогда выглядеть следующим образом, чтобы удалить элементы со значением, которое является нулевым:

val0 = true 
val1 = nil 
val2 = true 

h = { 
    :key0 => val0, 
    :key1 => val1, # I want to include this key only if val1 is not nil 
    :key2 => val2 
} 

h.delete_if{ |key, val| val.nil? } 

puts h #=> {:key0=>true, :key2=>true} 
0

Самым простым способом будет делать отборный:

{ :key0 => 1, :key1 => nil }.select {|_,v| v } 
#=> { :key0 => 1 } 

В этом случае, если v является «ложным» (либо false, либо nil), пара опускается.