我有一个哈希条目数组,并希望根据传递给函数的参数进行过滤。
如果哈希中有三个值A
,B
和C
,我想做类似的事情:
data = [{A:'a1', B:'b1', C:'c1'},
{A:'a1', B:'b2', C:'c1'},
{A:'a1', B:'b2', C:'c2'},
{A:'a2', B:'b1', C:'c1'},
{A:'a2', B:'b2', C:'c1'}]
data.find_all{ |d| d[:A].include?params[:A] }
.find_all{ |d| d[:B].include?params[:B] }
.find_all{ |d| d[:C].include?params[:C] }
找到所有A =='a1'和B ='b2'
的地方所以对于上面我得到:
{A:'a1',B:'b2',C:'c1'}和{A:'a1',B:'b2',C:'c2'}
*添加if
/ else
语句,如params.has_key? 'B'
,然后执行某些操作。
*每次将新类型的值添加到哈希映射时修改我的代码(比如现在我有'D')。
注意:哈希的键是一个符号,但值是一个字符串,我想做一个“包含”而不是“等于”。
我认为它是SQL Select语句,其中包含零或更多'=='子句
答案 0 :(得分:15)
如果我正确理解了您的问题,那么我相信select
课程的Array
方法可能会对您有所帮助。
select
获取一段代码,该代码块是数组中每个元素的测试条件。数组中满足该测试条件的任何元素都将被选中,结果是所选元素的数组。
例如:
arr = [ 4, 8, 15, 16, 23, 42 ]
result = arr.select { |element| element > 20 }
puts result # prints out [23, 42]
在你的例子中,你有一个哈希数组,这使得它比我的带有简单数字数组的例子稍微复杂一些。在您的示例中,我们有:
data = [{A:'a1', B:'b1', C:'c1'},
{A:'a1', B:'b2', C:'c1'},
{A:'a1', B:'b2', C:'c2'},
{A:'a2', B:'b1', C:'c1'},
{A:'a2', B:'b2', C:'c1'}]
我相信您希望代码执行的操作类似于:从我的数据数组中选择所有哈希值,其中哈希值:A
等于某个值,而:B
等于某些值其他价值。
假设您要查找:A == 'a1'
和:B == 'b2'
所有哈希值。你会这样做:
data.select { |hash_element| hash_element[:A] == 'a1' && hash_element[:B] == 'b2' }
这一行返回一个数组,其中包含原始数据数组中的哈希值,这些哈希值满足我们在块中提供的条件 - 即:A == 'a1'
和:B == 'b2'
中的哈希值。希望这有助于解决你的问题!
此处有关select
方法的更多信息:
http://www.ruby-doc.org/core-2.1.0/Array.html#method-i-select
已编辑 - 以下是对原始答案的补充
要跟进您之后关于if/else
条款和添加新参数的问题......您传递给select
的代码块当然可能比什么更复杂我在这个例子中写过。您只需记住这一点:如果代码块的最后一行的计算结果为true,则该元素将被选入结果数组。否则,它将不会被选中。
因此,这意味着您可以定义自己的函数,并在传递给select
的条件块中调用该函数。例如,像这样:
def condition_test(hash_element, key_values)
result = true
key_values.each do |pair|
if hash_element[pair[:key]] != pair[:value]
result = false
end
end
return result
end
# An example of the key-value pairs you might require to satisfy your select condition.
requirements = [ {:key => :A, :value => 'a1'},
{:key => :B, :value => 'b2'} ]
data.select { |hash_element| condition_test(hash_element, requirements) }
这使得您的条件阻止更加动态,而不是像我们在前面的示例中那样为:A == 'a1'
和:B == 'b2'
进行硬连接。您可以根据需要查找的键和值动态调整requirements
。您还可以修改condition_test
,而不仅仅是检查某个键的哈希值是否等于某个值。您可以在if/else
中添加condition_test
条款,以测试某些密钥的存在等内容。
答案 1 :(得分:0)
我认为你想使用.values_at(key)
http://www.ruby-doc.org/core-2.1.0/Hash.html#method-i-values_at values_at method