ruby-on-rails - find_all 数组中符合条件的元素?

标签 ruby-on-rails ruby

我有一个哈希条目数组,并希望根据传递给函数的参数进行过滤。

如果散列中有三个值,ABC,我想做类似的事情:

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' AND B='b2' 的地方

所以对于上面我得到: {A:'a1', B:'b2', C:'c1'} 和 {A:'a1', B:'b2', C:'c2'} * 放入 if/else 语句,比如 params.has_key? 'B' 然后做一些事情。 * 每次将新类型的值添加到 HashMap 时修改我的代码(假设现在我有“D”)。

注意:哈希的键是一个符号,但值是一个字符串,我想做一个“包含”而不是“等于”。

我认为它是带有零个或多个 '==' 子句的 SQL Select 语句

最佳答案

如果我对您的问题理解正确,那么我相信Array 类的select 方法可能对您有所帮助。

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' }

此行返回一个数组,其中包含原始数据数组中满足我们在 block 中提供的条件的那些散列 - 即 :A == 'a1':B == 'b2'。希望这有助于阐明您的问题!

有关 select 方法的更多信息,请点击此处:

http://www.ruby-doc.org/core-2.1.0/Array.html#method-i-select

已编辑 - 以下是对原始答案的补充

要跟进您稍后关于 if/else 子句和添加新参数的问题...您传递给 select 的代码块可以,当然,比我在例子中写的要复杂得多。您只需要牢记这一点:如果代码块的最后一行的计算结果为真,则该元素将被选入结果数组。否则不会被选中。

因此,这意味着您可以定义自己的函数,并在传递给 select 的条件 block 中调用该函数。例如,像这样:

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) }

这使您的条件 block 更加动态,而不是像我们那样硬连接 :A == 'a1':B == 'b2'在前面的例子中做了。您可以根据需要查找的键和值即时调整 requirements。您还可以修改 condition_test 来做更多的事情,而不仅仅是检查某个键的哈希值是否等于某个值。您可以在 condition_test 中添加 if/else 子句来测试某些键的存在等。

关于ruby-on-rails - find_all 数组中符合条件的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21566435/

相关文章:

mysql - 用于编辑集合的 Rails 表单

ruby-on-rails - Rails 相当于 Django 的 "sites"框架?

javascript - 与 JavaScript 相比,正则表达式在 Ruby 中表现不佳

html - Nokogiri XML 到节点

ruby - `def self.function` 名称是什么意思?

ruby-on-rails - rails + Angularjs : Module 'ngResource' is not available

javascript - 在 erb 中的 <% %> 内使用 javascript 变量 - Ruby on Rails

ruby - 多个schedule.rb文件与每当gem

ruby-on-rails - 全新的 Heroku CLI 安装认证失败

ruby-on-rails - 如何连接到redis-rb中的集群Azure Redis缓存?