У меня есть хеш, который выглядит примерно так:
params = { :irrelevant => "A String",
:choice1 => "Oh look, another one",
:choice2 => "Even more strings",
:choice3 => "But wait",
:irrelevant2 => "The last string" }
И я хочу простой способ отклонить все ключи, которые не являются выбором + int. Это может быть выбор1 или выбор1 - выбор10. Различается.
Как выделить ключи, выбрав только слово и цифру или цифры после них?
Бонус:
Превратите хеш в строку с символом табуляции (\ t) в качестве разделителя. Я сделал это, но потребовалось несколько строк кода. Обычно мастера-рубики могут делать это в одну или несколько строк.
Ответы:
Изменить на первоначальный ответ : Даже если этот ответ (на момент написания этого комментария) является выбранным ответом, оригинальная версия этого ответа устарела.
Я добавляю обновление здесь, чтобы помочь другим не отвлекаться на этот ответ, как я.
Как упоминается в другом ответе, Ruby> = 2.5 добавил
Hash#slice
метод, который ранее был доступен только в Rails.Пример:
Конец редактирования. Далее следует оригинальный ответ, который, я думаю, будет полезен, если вы используете Ruby <2.5 без Rails, хотя я полагаю, что на данном этапе это довольно необычный случай.
Если вы используете Ruby, вы можете использовать
select
метод. Вам нужно будет преобразовать ключ из символа в строку, чтобы выполнить регулярное выражение. Это даст вам новый хэш с выбором.или вы можете использовать
delete_if
и изменять существующий хэш, напримерили, если вам нужны только ключи, а не значения, вы можете сделать:
и это даст просто массив ключей, например,
[:choice1, :choice2, :choice3]
источник
.select
является.reject
, если это делает ваш код более идиоматических.#slice
меня способ работает на 2.5.3 даже без активной поддержки.В Ruby выбор Hash # является правильным вариантом. Если вы работаете с Rails, вы можете использовать Hash # slice и Hash # slice !. например (рельсы 3.2.13)
источник
Самый простой способ - включить
gem 'activesupport'
(илиgem 'active_support'
).Тогда в вашем классе вам нужно только
и позвонить
Я считаю, что не стоит декларировать другие функции, которые могут иметь ошибки, и лучше использовать метод, который был изменен в течение последних нескольких лет.
источник
Самый простой способ - включить гем 'activesupport' (или гем 'active_support').
params.slice(:choice1, :choice2, :choice3)
источник
Если вы работаете с рельсами и у вас есть ключи в отдельном списке, вы можете использовать
*
обозначение:Как уже говорилось в других ответах, вы также можете использовать,
slice!
чтобы изменить хеш на месте (и вернуть стертый ключ / значения).источник
Это одна строка, чтобы решить полный оригинальный вопрос:
Но большинство решений, приведенных выше, решают проблему, в которой вам нужно знать ключи заранее, используя
slice
или просто регулярное выражение.Вот еще один подход, который работает для простых и более сложных сценариев использования, который можно менять во время выполнения
Теперь это не только учитывает более сложную логику сопоставления ключей или значений, но также облегчает тестирование, и вы можете поменять логику сопоставления во время выполнения.
Ex для решения оригинальной проблемы:
источник
С
Hash::select
:источник
Если вам нужен оставшийся хеш:
или если вы просто хотите ключи:
источник
Поместите это в инициализатор
Тогда вы можете сделать
или
источник
источник
Что касается бонусного вопроса:
Если у вас есть вывод из
#select
метода, подобного этому (список 2-элементных массивов):затем просто возьмите этот результат и выполните:
Если у вас есть вывод из
#delete_if
метода, подобного этому (хэш):затем:
источник
map
принимает блок в качестве аргумента. Вы можете создать блок на лету, с&:method
конструкцией, которая создаст блок{|v| v.method }
. В моем случае&:last
был вызван массив (2-элементный массив) аргумент. Если вы хотите поиграть с ним, сначала проверьте, какой аргумент вы получаете в блок (получите 1 аргумент, не разбивайте его на несколько аргументов!) И попробуйте найти 1 метод (вы не можете связать методы с&:method
), который вернул бы вам то, что вы хотеть. Если это возможно, то вы можете использовать ярлык, если нет, то вам нужен полный блокисточник
У меня была похожая проблема, в моем случае решение было одним вкладышем, который работает, даже если ключи не являются символами, но вы должны иметь ключи критериев в массиве
Другой пример
источник