Find key/value pairs deep inside a hash containing an arbitrary number of nested hashes and arrays

前端 未结 9 1044
天涯浪人
天涯浪人 2020-12-02 20:12

A web service is returning a hash that contains an unknown number of nested hashes, some of which contain an array, which in turn contains an unknown number of nested hashes

相关标签:
9条回答
  • 2020-12-02 20:51

    Ruby 2.3 introduces Hash#dig, which allows you to do:

    h = { foo: {bar: {baz: 1}}}
    
    h.dig(:foo, :bar, :baz)           #=> 1
    h.dig(:foo, :zot)                 #=> nil
    
    0 讨论(0)
  • 2020-12-02 20:56

    Combining a few of the answers and comments above:

    class Hash
      def deep_find(key, object=self, found=nil)
        if object.respond_to?(:key?) && object.key?(key)
          return object[key]
        elsif object.is_a? Enumerable
          object.find { |*a| found = deep_find(key, a.last) }
          return found
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-02 20:59

    Despite this appearing to be a common problem, I've just spent a while trying to find/come up with exactly what I need, which I think is the same as your requirement. Neither of the links in the first response are spot-on.

    class Hash
      def deep_find(key)
        key?(key) ? self[key] : self.values.inject(nil) {|memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
      end
    end
    

    So given:

    hash = {:get_transaction_list_response => { :get_transaction_list_return => { :transaction => [ { ... 
    

    The following:

    hash.deep_find(:transaction)
    

    will find the array associated with the :transaction key.

    This is not optimal as the inject will continue to iterate even if memo is populated.

    0 讨论(0)
提交回复
热议问题