How to replace a hash key with another key

后端 未结 11 1476
青春惊慌失措
青春惊慌失措 2020-12-04 07:36

I have a condition where, I get a hash

  hash = {\"_id\"=>\"4de7140772f8be03da000018\", .....}

and I want this hash as

         


        
11条回答
  •  情歌与酒
    2020-12-04 08:06

    I went overkill and came up with the following. My motivation behind this was to append to hash keys to avoid scope conflicts when merging together/flattening hashes.

    Examples

    Extend Hash Class

    Adds rekey method to Hash instances.

    # Adds additional methods to Hash
    class ::Hash
      # Changes the keys on a hash
      # Takes a block that passes the current key
      # Whatever the block returns becomes the new key
      # If a hash is returned for the key it will merge the current hash 
      # with the returned hash from the block. This allows for nested rekeying.
      def rekey
        self.each_with_object({}) do |(key, value), previous|
          new_key = yield(key, value)
          if new_key.is_a?(Hash)
            previous.merge!(new_key)
          else
            previous[new_key] = value
          end
        end
      end
    end
    

    Prepend Example

    my_feelings_about_icecreams = {
      vanilla: 'Delicious',
      chocolate: 'Too Chocolatey',
      strawberry: 'It Is Alright...'
    }
    
    my_feelings_about_icecreams.rekey { |key| "#{key}_icecream".to_sym }
    # => {:vanilla_icecream=>"Delicious", :chocolate_icecream=>"Too Chocolatey", :strawberry_icecream=>"It Is Alright..."}
    

    Trim Example

    { _id: 1, ___something_: 'what?!' }.rekey do |key|
      trimmed = key.to_s.tr('_', '')
      trimmed.to_sym
    end
    # => {:id=>1, :something=>"what?!"}
    

    Flattening and Appending a "Scope"

    If you pass a hash back to rekey it will merge the hash which allows you to flatten collections. This allows us to add scope to our keys when flattening a hash to avoid overwriting a key upon merging.

    people = {
      bob: {
        name: 'Bob',
        toys: [
          { what: 'car', color: 'red' },
          { what: 'ball', color: 'blue' }
        ]
      },
      tom: {
        name: 'Tom',
        toys: [
          { what: 'house', color: 'blue; da ba dee da ba die' },
          { what: 'nerf gun', color: 'metallic' }
        ]
      }
    }
    
    people.rekey do |person, person_info|
      person_info.rekey do |key|
        "#{person}_#{key}".to_sym
      end
    end
    
    # =>
    # {
    #   :bob_name=>"Bob",
    #   :bob_toys=>[
    #     {:what=>"car", :color=>"red"},
    #     {:what=>"ball", :color=>"blue"}
    #   ],
    #   :tom_name=>"Tom",
    #   :tom_toys=>[
    #     {:what=>"house", :color=>"blue; da ba dee da ba die"},
    #     {:what=>"nerf gun", :color=>"metallic"}
    #   ]
    # }
    
    

提交回复
热议问题