wake-up-neo.com

So ersetzen Sie einen Hash-Schlüssel durch einen anderen Schlüssel

Ich habe eine Bedingung, wo ich einen Hash bekomme 

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

und ich möchte diesen Hash als

  hash = {"id"=>"4de7140772f8be03da000018", ......}

P.S : Ich weiß nicht, was die Schlüssel im Hash sind, sie sind zufällig, was mit einem "_" - Präfix für jeden Schlüssel kommt und ich möchte keine Unterstriche

160
Manish Das

Wenn alle Schlüssel Strings sind und alle das Unterstrich-Präfix haben, können Sie den Hash mit folgendem Patch aktualisieren:

h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }

Das k[1, k.length - 1] - Bit erfasst alle Variablen von k mit Ausnahme des ersten Zeichens. Wenn Sie eine Kopie wünschen, dann:

new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]

Oder

new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }

Sie können auch sub verwenden, wenn Sie die k[]-Notation nicht für das Extrahieren eines Teilstrings mögen:

h.keys.each { |k| h[k.sub(/\A_/, '')] = h[k]; h.delete(k) }
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }

Und wenn nur einige der Schlüssel das Unterstrich-Präfix haben:

h.keys.each do |k|
    if(k[0,1] == '_')
        h[k[1, k.length - 1]] = h[k]
        h.delete(k)
    end
end

Ähnliche Modifikationen können an allen anderen oben genannten Varianten vorgenommen werden, außer diesen beiden:

Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }

sollte mit Schlüsseln, die keine Unterstriche ohne zusätzliche Modifikationen enthalten, in Ordnung sein.

33
mu is too short
hash[:new_key] = hash.delete :old_key
628
gayavat

Rails Hash hat eine Standardmethode dafür:

hash.transform_keys{ |key| key.to_s.upcase }

http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys

UPD: Ruby 2.5-Methode

116
gayavat

du kannst tun 

hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}

Das sollte für Ihren Fall funktionieren! 

14
Sadiksha Gautam
h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
10
DigitalRoss

Wenn wir einen bestimmten Schlüssel in Hash umbenennen möchten, können wir dies wie folgt tun:
Angenommen, mein Hash ist my_hash = {'test' => 'Ruby hash demo'}
Nun möchte ich 'test' durch 'message' ersetzen, dann:
my_hash['message'] = my_hash.delete('test')

10
hash.each {|k,v| hash.delete(k) && hash[k[1..-1]]=v if k[0,1] == '_'}
2
maerics

Ich bin übertrieben und habe mir folgendes ausgedacht. Meine Motivation dahinter war, an Hash-Schlüssel anzuhängen, um beim Zusammenführen/Reduzieren von Hashes Konflikte zu vermeiden.

Beispiele

Hash-Klasse erweitern

Fügt den Hash-Instanzen eine rekey-Methode hinzu.

# 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

Beispiel voranstellen

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..."}

Beschnittbeispiel

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

Reduzieren und Anhängen eines "Bereichs"

Wenn Sie einen Hash zurückgeben, um ihn erneut zu verschlüsseln, wird der Hash zusammengeführt, sodass Sie Sammlungen reduzieren können. Auf diese Weise können wir beim Reduzieren eines Hashs einen Bereich zu unseren Schlüsseln hinzufügen, um das Überschreiben eines Schlüssels beim Zusammenführen zu vermeiden.

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

1
CTS_AE