Ruby: Get all keys in a hash (including sub keys)

前端 未结 10 985
清歌不尽
清歌不尽 2021-01-31 19:02

let\'s have this hash:

hash = {\"a\" => 1, \"b\" => {\"c\" => 3}}
hash.get_all_keys 
=> [\"a\", \"b\", \"c\"]

how can i get all key

10条回答
  •  不要未来只要你来
    2021-01-31 19:28

    Version that keeps the hierarchy of the keys

    • Works with arrays
    • Works with nested hashes

    keys_only.rb

    # one-liner
    def keys_only(h); h.map { |k, v| v = v.first if v.is_a?(Array); v.is_a?(Hash) ? [k, keys_only(v)] : k }; end
    
    # nicer
    def keys_only(h)
      h.map do |k, v|
        v = v.first if v.is_a?(Array);
    
        if v.is_a?(Hash)
          [k, keys_only(v)]
        else
          k
        end
      end
    end
    
    hash = { a: 1, b: { c: { d: 3 } }, e: [{ f: 3 }, { f: 5 }] }
    keys_only(hash)
    # => [:a, [:b, [[:c, [:d]]]], [:e, [:f]]]
    

    P.S.: Yes, it looks like a lexer :D

    Bonus: Print the keys in a nice nested list

    # one-liner
    def print_keys(a, n = 0); a.each { |el| el.is_a?(Array) ? el[1] && el[1].class == Array ? print_keys(el, n) : print_keys(el, n + 1) : (puts "  " * n + "- #{el}") }; nil; end
    
    # nicer
    def print_keys(a, n = 0)
      a.each do |el|
        if el.is_a?(Array)
           if el[1] && el[1].class == Array
             print_keys(el, n)
           else
             print_keys(el, n + 1)
           end
        else
          puts "  " * n + "- #{el}"
        end
      end
    
      nil
    end
    
    
    > print_keys(keys_only(hash))
    - a
      - b
          - c
            - d
      - e
        - f
    

提交回复
热议问题