2016-12-27 124 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 &&'''***总是***评估为'''' - 看到问题在这里? :) –