检查哈希映射数组中是否存在特定值

Check if certain value exists in array of hash map

我有一个散列映射数组。它看起来像这样:

params = []
CSV.foreach(......) do
  one_line_item = {}
  one_line_item[:sku] = "Hello"
  one_line_item[:value] = "20000"
  params << one_line_item
end

我想检查 :sku 是否在这个散列数组中。我是这样做的:

# Reading new line of csv in a hash and saving it in a temporary variable (Say Y)
params.each do |p|
  if p[:sku] == Y[:sku]
    next
  end
end

我正在遍历每个sku值的完整列表,因此时间复杂度正在折腾[O(n^2)],不用说它没有用。

有什么方法可以使用 include?

如果我能一次从整个数组中获取与键 :sku 对应的值数组,这将解决我的问题。 (我知道我可以为这些值维护另一个数组,但我想避免这种情况)

一个参数示例

params = [{:sku=>"hello", :value=>"5000"}, {:sku=>"world", :value=>"6000"}, {:sku=>"Hi", :value=>"7000"}]

所以你想要的是收集所有SKU的列表。您是否在查找键 sku => 值?

Hash[*params.map { |p| [p[:sku], p[:value]] }.flatten]

这将为您提供每个 sku 到值的映射,然后您可以使用 sku_hash.key?(tester)

进行快速键查找

any? and include? 方法听起来正是您所需要的。

示例:

params.any? { |param| param.include?(:sku) }

这是一种有效的方法,因为它 "short circuits",一旦找到匹配就停止。

您可以使用 rails_param gem 来做同样的事情。我发现它是一个非常有用的实用程序,用于在控制器中验证请求参数:

https://github.com/nicolasblanco/rails_param

# primitive datatype syntax
param! :integer_array, Array do |array,index|
  array.param! index, Integer, required: true
end

# complex array
param! :books_array, Array, required: true  do |b|
  b.param! :title, String, blank: false
  b.param! :author, Hash, required: true do |a|
    a.param! :first_name, String
    a.param! :last_name, String, required: true
  end
  b.param! :subjects, Array do |s,i|
    s.param! i, String, blank: false
  end
end