1

我有一个看起来像这样的哈希数组(array1):

array1 = [
           {:ID=>"1", :value=>"abc"},
           {:ID=>"2", :value=>"def"}
         ]

我可以遍历每个哈希并手动检查每个哈希值:

array1.each do |h|
  if h.has_value?("def")
    #do something
  end
end

有没有办法检查哈希值“abc”是否存在于数组内部的哈希中,而不必遍历数组?

4

4 回答 4

2

find方法是数组最简洁的方法。

array1.find { |item| item[:value] == 'abc' }

无论如何,如果您可以直接从散列开始更好,但如果您必须从数组切换到散列以进行 O(1) 查找,无论如何它可能会更慢。

于 2017-04-21T20:42:57.283 回答
2

使用any?而不是每个,如果发现它会在早期阶段中断,最好的情况 O(1) 和最坏的情况 O(n)

word = "def"
is_present = array1.any? { |h| h.has_value?(word) }

is_present 是true如果word在散列中找到,否则false

于 2017-04-21T20:43:36.570 回答
1

一种或另一种方式,您无法避免迭代数组。这是一种方法。

array1.flat_map(&:values).include?("def")
  #=> true

笔记

array1.flat_map(&:values)
  #=> ["1", "abc", "2", "def"]
于 2017-04-21T22:10:04.657 回答
0

您显然必须对数组的元素至少迭代一次。

如果你经常这样做,你应该使用另一种数据格式:

array1 = [
  { ID: '1', value: 'abc' },
  { ID: '2', value: 'def' },
  { ID: '3', value: 'abc' }
]

lookup_table = array1.each_with_object(Hash.new { |h, k| h[k] = [] }) do |hash, table|
  table[hash[:value]] << hash[:ID]
end

p lookup_table
# {"abc"=>["1", "3"], "def"=>["2"]}
p lookup_table['abc']
# ["1", "3"]

作为奖励,它会为您提供ID找到该值的所有 s,并且它会快速提供。

如果您只想知道哈希值是否存在,您可以使用Set

require 'set'
all_values = Set.new(array1.map{|h| h[:value]})
p all_values.include? 'abc'
# true
p all_values.include? 'xyz'
# false

同样,查找将比使用哈希数组快得多。

于 2017-04-21T22:30:13.117 回答