代码之家  ›  专栏  ›  技术社区  ›  Jason

使用ruby,检查散列中的任何键是否与数组中的任何值匹配的最有效方法是什么?

  •  0
  • Jason  · 技术社区  · 16 年前

    我想将参数散列中的键与元素数组中的键进行比较,以便进行匹配。

    例如:

    params          = {"key1", "key2", "key3"}
    params_to_match = ["key2","key3"]
    

    我可以这样做,但我相信有一种更优雅的方法可以达到同样的效果

    params.each_key{|key|
      if params_to_match.include?(key.to_s)
        return
      end
    }
    
    4 回复  |  直到 16 年前
        1
  •  3
  •   Arkku    16 年前

    不一定更多 有效率的 但也许更多 优雅的 从某种意义上说:

    return unless (params.keys & params_to_match).empty?
    

    与您的示例相比(在一般情况下,不一定是这样一个小的玩具示例),一个更有效的方法是检查哈希是否包含键,因为从数组中查找这些键的时间实际上是恒定的。所以,你的例子会变成这样:

    params_to_match.each { |p| return if params.has_key?(p) }
    
        2
  •  2
  •   maček    16 年前

    使用 &

    Set intersection返回一个新数组,其中包含两个数组共有的元素,没有重复项。

    [ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]
    
    params.keys & params_to_match  #=> ["key2", "key3"]
    
        3
  •  1
  •   mckeed    16 年前

    我认为优雅和高效的最佳结合是

    return if params_to_match.any? { |p| params.has_key?(p) }
    

    如果你有积极的支持,你可以

    return if params.slice(*params_to_match).any?
    
        4
  •  -1
  •   wilhelmtell    16 年前

    这是psedudocode中的一个快速算法。

    assert keys, input are sorted
    pos = beginning of keys
    for i in input
      pos = keys.find(pos, i)  # find() starts search at position pos
      if not_found(pos) then return false
      ++pos
    return true
    

    该算法假设密钥和输入是以0(n+m)开始排序的,n和m是密钥和输入的计数。我把它留给你翻译成ruby,但是要注意 find() 功能;it 必须 在上一次迭代中找到的位置开始搜索,而不是在键的开头。否则,你就只剩下o(n^2+m),n个键了。

    推荐文章