Какой (самый быстрый / чистый / простой) способ преобразовать все ключи в хэше из строк в символы в Ruby?
Это было бы удобно при разборе YAML.
my_hash = YAML.load_file('yml')
Я хотел бы иметь возможность использовать:
my_hash[:key]
Скорее, чем:
my_hash['key']
hash.symbolize_keys
иhash.deep_symbolize_keys
делать работу, если вы используете Rails.Ответы:
В Ruby> = 2.5 ( документы ) вы можете использовать:
Используете более старую версию Ruby? Вот одна строка, которая скопирует хэш в новый с символизированными ключами:
С Rails вы можете использовать:
источник
each_with_object
так:my_hash.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
.tap
метод, чтобы избавиться от необходимости проходитьmemo
в конце. Я создал очищенную версию всех решений (в том числе и рекурсивных) gist.github.com/Integralist/9503099Вот лучший способ, если вы используете Rails:
Титулы.symbolize_keys
Конец.
Если нет, просто сорвите их код (он также есть в ссылке):
источник
symbolize_keys
с новым и рабочим (Rails 3) URL. Первоначально я просто исправил URLto_options
, но по этой ссылке нет документации.symbolize_keys
на самом деле есть описание, поэтому я использовал его вместо.hash.stringify_keys
работает.Для конкретного случая YAML в Ruby, если ключи начинаются с '
:
', они будут автоматически вставлены как символы.Вывод:
источник
YAML#load_file
по умолчанию все ключи к символам вместо строк без необходимости начинать каждый ключ с двоеточия?Еще более кратко:
источник
my_hash.map { |k, v| [k.to_sym, v] }.to_h
если вы используете Rails, это намного проще - вы можете использовать HashWithIndifferentAccess и обращаться к ключам как в виде строки, так и в виде символов:
смотрите также:
http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html
Или вы можете использовать удивительный Gem "Facets of Ruby", который содержит множество расширений для классов Ruby Core и Standard Library.
см. также: http://rubyworks.github.io/rubyfaux/?doc=http://rubyworks.github.io/facets/docs/facets-2.9.3/core.json#api-class-Hash
источник
Так как
Ruby 2.5.0
вы можете использоватьHash#transform_keys
илиHash#transform_keys!
.источник
stringify_keys
илиsymbolize_keys
.http://api.rubyonrails.org/classes/Hash.html#method-i-symbolize_keys
источник
Вот способ глубоко символизировать объект
источник
Мне очень нравится камень Mash .
Вы можете сделать
mash['key']
, илиmash[:key]
, илиmash.key
источник
Если вы используете json и хотите использовать его как хеш, в ядре Ruby вы можете сделать это:
symbolize_names : если установлено значение true, возвращает символы для имен (ключей) в объекте JSON. В противном случае строки возвращаются. Строки по умолчанию.
Док: Json # parse symbolize_names
источник
symbol_hash = JSON.parse(JSON.generate(YAML.safe_load(FILENAME)), symbolize_names: true)
это довольно СУХОЙ (но неэффективный) способ быстро получить хеш с вложенными ключами в качестве символов, если он исходит из файла YAML.params.symbolize_keys
тоже будет работать. Этот метод превращает ключи хеша в символы и возвращает новый хеш.источник
Модификация ответа @igorsales
источник
В Rails вы можете использовать:
Преобразует в:
источник
deep_symbolize_keys
добавлено в расширение Hash в Rails , но не является частью ядра Ruby.Здесь так много ответов, но функция одного метода -
hash.symbolize_keys
источник
Это мой единственный вкладыш для вложенных хэшей
источник
В случае , если причина , что вам нужно сделать это , потому что ваши данные изначально пришли из JSON, вы можете пропустить какое - либо из этого разбора, просто передав
:symbolize_names
опции при глотании JSON.Rails не требуется и работает с Ruby> 1.9
источник
Вы могли бы быть ленивыми, и обернуть это в
lambda
:Но это будет работать только для чтения из хэша, а не для записи.
Для этого вы можете использовать
Hash#merge
Блок init будет преобразовывать ключи один раз по требованию, хотя если вы обновите значение для строковой версии ключа после доступа к версии символа, версия символа не будет обновлена.
Вы могли бы также сделать так, чтобы блок init не обновлял хеш, что защитило бы вас от такого рода ошибок, но вы все равно были бы уязвимы к противоположному - обновление версии символа не будет обновлять строковую версию:
Поэтому с этим нужно быть осторожнее, переключаясь между двумя ключевыми формами. Придерживайся одного.
источник
Будет ли что-то вроде следующей работы?
Он скопирует хеш, но большую часть времени вас это не волнует. Вероятно, есть способ сделать это без копирования всех данных.
источник
более короткий однострочный выпуск:
источник
Как насчет этого:
источник
Это для людей, которые используют
mruby
и не имеют никакогоsymbolize_keys
определенного метода:Метод:
String
RuntimeError
источник
!
инsymbolize_keys
. В остальном работает нормально.Массив, который мы хотим изменить.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
Создайте новую переменную как пустой массив, чтобы мы могли ".push" символы в.
символы = []
Здесь мы определяем метод с блоком.
strings.each {| x | symbols.push (x.intern)}
Конец кода.
Так что это, вероятно, самый простой способ конвертировать строки в символы в ваших массивах в Ruby. Создайте массив строк, затем создайте новую переменную и установите переменную в пустой массив. Затем выберите каждый элемент в первом массиве, который вы создали с помощью метода .each. Затем используйте код блока для «.push» всех элементов в вашем новом массиве и используйте «.intern или .to_sym» для преобразования всех элементов в символы.
Символы быстрее, потому что они экономят больше памяти в вашем коде, и вы можете использовать их только один раз. Символы чаще всего используются для ключей в хэше, и это здорово. Я не лучший программист на ruby, но эта форма кода мне очень помогла. Если кто-нибудь знает лучший способ, поделитесь им, и вы можете использовать этот метод и для хэширования!
источник
Если вы хотите ванильное рубиновое решение, и у меня нет доступа к нему,
ActiveSupport
это глубокое символизирующее решение (очень похожее на предыдущие)источник
Начиная с Psych 3.0 вы можете добавить symbolize_names: вариант
Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
Примечание: если у вас более низкая версия Psych, чем 3.0,
symbolize_names:
она будет игнорироваться.Мой Ubuntu 18.04 включает его из коробки с ruby 2.5.1p57
источник
источник
a
заключить в скобки, чтобы разложить аргумент блока, чтобы сделать его еще более кратким. Смотрите мой ответ для примера.Это не совсем одна строка, но она превращает все строковые ключи в символы, в том числе вложенные:
источник
Мне нравится эта строка, когда я не использую Rails, потому что тогда мне не нужно делать второй хеш и хранить два набора данных во время обработки:
Hash # delete возвращает значение удаленного ключа
источник
Facets 'Hash # deep_rekey также является хорошим вариантом, особенно:
Образец:
источник
В ruby я считаю, что это самый простой и понятный способ превратить строковые ключи в хешах в символы:
Для каждого ключа в хеше мы вызываем delete для него, который удаляет его из хеша (также delete возвращает значение, связанное с удаленным ключом ), и мы немедленно устанавливаем его равным символизированному ключу.
источник
Аналогично предыдущим решениям, но написано немного по-другому.
Код не изменяет переданный хэш
источник