2012-11-09 28 views
18

考慮:Rails的:尋找數組的最大可能含有零

shipping_costs = { 
    key1: 45, 
    key2: 99, 
    key3: nil, 
    key4: 24 
} 

什麼讓那些假設零= 0鍵的最大最乾淨的方式是什麼?

如果我在運行Rails的控制檯直shipping_costs.values.max我得到這樣的:最大運行之前,把這些尼爾斯到零

ArgumentError: comparison of Fixnum with nil failed 

乾淨的方式?

回答

25

我會去:

shipping_costs.values.map(&:to_i).max 

nil.to_i0

+2

這個問題在技術上最正確和具體,所以你可以得到答案。我可能會做湯姆的解決方案。 :) –

+1

這裏有一個潛在的錯誤來源,那就是當你想要-1時,這會返回數組[nil,-2,-4,-1]的最大值爲零。出於這個原因,我寧願@toniedzwiedz的解決方案。 – isthmuses

+0

雖然'nil'值應該被假定爲'= 0',但問題確實指定了。 – Shadwell

2

shipping_costs.values.reject {|v| v.nil? }.max

+1

'reject'更清潔,然後'select'與'not'結合。 'compact'更簡潔,但是當所有的fixnums都是負數並且nil是最大值時,所有這些失敗。 – steenslag

+0

謝謝。我知道有類似的東西,但從來沒有使用它 –

+0

@IsmaelAbreu compact在負數不會失敗,它只是刪除零值並選擇負值與絕對值最低。 – toniedzwiedz

28

如果你想保留它確實簡潔,您可以使用 shipping_costs.values.compact.max

compact方法刪除數組中的所有nil值。

其他答案也是好主意。但是,我更願意拒絕這些值,而不是用數字替換它們。我認爲最好知道一個數組只包含nil的值,而不是猜測0(或您選擇的任何值)來自哪裏。

+0

好,乾淨的答案!如果所有值都爲零,我將不得不檢查零。 '[] .max' =>零。 –

+0

@JamonHolmgren我認爲最好知道它只包含'nil'值而不是猜測'0'來自何處;) – toniedzwiedz

+0

是的,你可能是對的。 –

5

max需要一個塊,讓你做一個比較,類似於如何sort作品:

[45, 99, nil, 24].max{ |a,b| (a || 0) <=> (b || 0) } 
=> 99 

或:

[45, 99, nil, 24].max{ |a,b| a.to_i <=> b.to_i } 
=> 99 

這可以讓你強迫你怎麼想/需要的價值,在比較發生之前。

對於你的情況,shipping_costs.values將返回你需要比較數組,所以:

shipping_costs.values.max{ |a,b| a.to_i <=> b.to_i } 
+0

這不會對僅含有負值的數組,如果其中'nil'將被返回的最大元素('nil.to_i'返回0)工作。但是,在這種特定情況下,該數組包含*費用*,因此很難指望出現負值。 +1 – toniedzwiedz

6

沒有人提到更短的形式?

shipping_costs.values.max_by(&:to_i) 

(只是一個資訊)