2011-12-11 21 views
2

我有一個Ruby的API,採取一系列布爾開關,沿東西線的工作:轉換紅寶石Array對散列鍵值對,其中的值是一個常數

validate({ :can_foo => true, :can_bar => false, :can_baz => true, ... }) 

我m編寫了一系列測試來驗證API的行爲是否應該如此,所以我需要構建很多組交換機。繼續輸入:foo => true總是顯得很浪費,所以我想我會寫一些Ruby的ditty來將數組轉換爲這種結構,例如,

true_vals = %w(these are my true items) 
false_vals = %w(these are my false items) 

convert = lambda{ |arr, truthiness| arr.inject({}){ |res, key| res.update(key=>truthiness) } } 
falsify = lambda{ |arr| convert.call(arr, false) } 
truthify = lambda{ |arr| convert.call(arr, true) } 

validate(truthify.call(true_vals).merge(falsify.call(false_vals))) 

這似乎比簡單地輸入一長串:sym => [true | false]對更好嗎?有一個更好的方法嗎? (我以true_vals.inject({}){| res,key | res.update(key => true)}開始}但是感覺不夠乾燥;我必須複製粘貼& s /真/假/做真假難辨;而我做了很多很多次這樣一個lambda似乎是合理的)

感謝,

- 馬特

+0

你只是試圖自動映射'true_vals'到'true'和'false_vals'到'false'的每個元素? – Linuxios

+0

是的。不是通用的「轉換數組哈希」,大多數人都有... –

+0

我可以做true_vals.inject({}){| res,key | res.update(key => true)}但是感覺不夠乾淨;我不得不復制粘貼來做假... –

回答

4
cs = { true => [:y, :yes], 
     false => [:n, :no] } 
Hash[cs.map{ |k, vs| vs.map{ |v| [v, k] } }.flatten(1)] 
#=> {:y=>true, :yes=>true, :no=>false, :n=>false} 
+1

+1,就是這樣,更多的哈希[]和更少的注入(除非我們得到混搭)。可選:'Hash [cs.flat_map {| k,vs | vs.product([k])}]' – tokland

1

這裏是一個解決方案:

switches={} 
true_vals.each do |v| 
    switches[v]=true 
end 
false_vals.each do |v| 
    switches[v]=false 
end 
+0

我不討厭它,但這意味着在我寫的每一個測試中,我必須這樣做。這並不可怕,但它不會感覺非常乾燥。 –

+0

你可以把它包裝在一個方法中。再次,它不是很優雅,但它更容易理解。 – Linuxios