Переименовать ключ хеша, но сохранить порядок (без вставки нового) - PullRequest
0 голосов
/ 17 декабря 2018

Я хочу переименовать ключ хеша.Это:

myhash[preferred_name] = myhash.delete old_name 

вставляет новую пару ключ-значение в последний индекс моего хэша.Есть ли способ переименовать хеш без добавления нового?

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Я второй @ ответ Стефена, при условии, что нет необходимости поддерживать версии Ruby до версии 2.5, когда дебютировал Hash # transform_keys! .Если более ранние версии должны поддерживаться, здесь есть один способ (который не создает новый хеш), расширение подхода, упомянутого в OP.

h = { foo: 1, bar: 2, baz: 3 }

h.keys.each { |k| h[k == :bar ? :qux : k] = h.delete(k) }
  #=> [:foo, :bar, :baz] 
h #=> {:foo=>1, :qux=>2, :baz=>3}

Обратите внимание, что перечислители Hash # each_key и Хэш # каждый не может использоваться, поскольку ключи удаляются во время итерации.

Другой выбор следующий:

keys = h.keys
keys[keys.index(:bar)] = :qux
h.replace(keys.zip(h.values).to_h)
  #=> {:foo=>1, :qux=>2, :baz=>3}
0 голосов
/ 18 декабря 2018
myhash.to_a.each { |a| a[0] = preferred_name if a[0] == old_name }.to_h

Или:

h.map { |k, v| [k == old_name ? preferred_name : k, v] }.to_h

К сожалению, оба решения будут сканировать всю структуру - даже после того, как совпадение найдено - поэтому, если в вашем хэше много записей, вы можете предпочесть один из других вариантов.

0 голосов
/ 17 декабря 2018

Вы можете использовать transform_keys!:

h = { foo: 1, bar: 2, baz: 3 }

h.transform_keys! { |k| k == :bar ? :qux : k }
#=> {:foo=>1, :qux=>2, :baz=>3}

Просто убедитесь, что новый ключ еще не присутствует в хэше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...