2016-12-27 61 views
1

我有params,看起來像這樣:如何從一組哈希中過濾哈希?

params = [{:limit=>5}, {:skip=>0}, {:asc=>""}, {:desc=>""}] 

我想刪除哈希表元素的值是0或空字符串。我試着這樣做:

params.reject { |h| h.values !== 0 } 

但是這給了我一個語法錯誤

也試過:

params.select { |h| h.values != 0 || h.values != "" } 

但是這給我什麼。我究竟做錯了什麼?

+2

提示:什麼'h.values'返回?你真的可以把它比作零? –

回答

2

而不必與只有一對的|key,value|散列數組的,你可以只合並所有散列值來獲得一個大的哈希值。

它變得更容易去除不需要的值,它也變得更容易獲取信息:

params = [{ limit: 5 }, { skip: 0 }, { asc: '' }, { desc: '' }] 

hash = params.inject(&:merge).reject{|_, value| value == 0 || value == '' } 
# => {:limit=>5} 

hash[:limit] 
# => 5 

隨着哈希的數組,你必須寫:

(h = array_of_hashes.find{|h| h.keys.include?(:limit)}) && h[:limit] 
#=> 5 
+0

我有點困惑。提問者不想要返回一個數組?國際海事組織,最後一行一直用一個醜陋的棍棒。既然你需要本地變量,不會有兩行更好嗎? –

+0

我想不出有什麼好的理由,只需要一個散列就可以有一對哈希數組。最後一行可能不是最漂亮的,但是從哈希數組中檢索值並不容易。不,我們不需要'h',只需要'h [:limit]',但只有在找到'h'時才需要。 –

+0

埃裏克,一個人可能想要一個大小爲一的散列數組而不是散列數組的情況是,當有重複的鍵時:如果'params = [{limit:5},{limit:''}]'你會返回一個空的哈希,但不會提問者期望'[{limit:5}]'? –

3

你有一個散列數組,所以你必須對每個散列進行操作。

params.reject { |hash| hash.any? { |_, v| [0, ''].include?(v) }} 
#=> [{:limit=>5}] 
+0

我得到'undefined method zero?' –

0

我發現兩種方法可以做到這一點:

filtered = params.reject { |hash| hash.values.any? { |v| v.to_i == 0 } } 

filtered = params.select { |hash| hash.values.none? { |val| val == '' || val == 0 } } 
+4

第二個選擇是更好的,因爲任何字符串(如果它不是以整數開始)轉換爲整數是'0'。 –

+1

@Andrey,就像是說,「第二種選擇更好,因爲一加一不等於三」。總是一個輕描淡寫,呃? (不過,好點。) –

0

與包括也將解決這個問題,使用拒絕。

params.reject { |key| key.values.include?(0) || key.values.include?("") } 
+0

這個解決方案沒有考慮OP的空字符串部分。一旦它完成(在你的潛在編輯之後),它與OP已經有的不一樣了。 –

+0

簡單使用&&運算符.. –

+0

'0 &&'''***總是***評估爲'''' - 看到問題在這裏? :) –