【问题标题】:check hash value within an array检查数组中的哈希值
【发布时间】:2017-04-21 20:33:06
【问题描述】:

我有一个哈希数组 (array1),如下所示:

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

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

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

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

【问题讨论】:

  • 是的,不要使用数组。它消除了查找哈希表的O(1) 点。只需为此使用 JS 对象文字。
  • array1是从哪里来的,是怎么产生的?是否可以在array1 的原点更改结构(例如更改为哈希)?
  • 您认为"1" 是您的数组散列中的一个值吗?
  • 是的,根据定义,“1”和“abc”是哈希值。其中“ID”和“值”是键。

标签: arrays ruby ruby-hash


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    如果在哈希中找到word,则is_present 为true,否则为false

    【讨论】:

    • 但这会遍历数组,OP 不想这样做,仍然是O(n)
    • 是的,你最终必须迭代,但是 ruby​​ 有吗?这简化了我们的工作,你将如何通过正确迭代来找到数组中的元素。
    • @SpencerWieczorek 没有避免迭代,但是any? 将在第一个true 值处停止处理,从而避免全数组扫描。
    • @MarkThomas 你当然可以避免迭代,OP 正在寻求 XY 问题的解决方案。
    • @SpencerWieczorek 同意。数组不是最好的起点。
    【解决方案3】:

    无论如何,您都无法避免对数组进行迭代。这是一种方法。

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

    注意

    array1.flat_map(&:values)
      #=> ["1", "abc", "2", "def"]
    

    【讨论】:

    • 从问题来看,我不知道"1""2"是否应该在这里。
    【解决方案4】:

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

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

    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"]
    

    作为奖励,它会为您提供找到此值的所有IDs,而且速度很快。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-20
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      相关资源
      最近更新 更多