Ключ, связанный с хэшем ruby, комбинированный

Я хочу объединить связанный ключ, например:

my_hash = {key_a: "value a", key_b: "value b", key_c: "value c"}

Я хочу, чтобы результат был:

{ key:
  [
    { a: "value a" },
    { b: "value b" },
    { c: "value c" }
  ]
}

Это можно легко сделать, получая каждый ключ явно, но проблема в том, что он может определять динамический ключ.

ПРОБЛЕМА в том, что key_ может быть любой, нельзя определить, что после key_. Это может быть key_r, key_w, key_z

Используйте функцию сопоставления, которая будет проверять или сопоставлять слово key_ или функции, такие как включение или использование регулярных выражений.

tp45 09.05.2023 08:59

Почему вы используете версию Ruby on Rails, которая не поддерживалась в течение многих лет и имеет неисправленные ошибки и уязвимости в системе безопасности? Почему вы используете две версии Ruby on Rails в одном проекте? Какое это имеет отношение к Ruby on Rails?

Jörg W Mittag 09.05.2023 09:29

Похоже, вы хотите разделить имя ключа на _, а затем сгруппировать результаты.

Stefan 09.05.2023 09:47
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
3
53
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Я бы сделал это так:

my_hash = { key_a: "value a", key_b: "value b", key_c: "value c" }

my_hash.each_with_object({}) do |(key, value), result| 
  prefix, suffix = key.to_s.split('_').map(&:to_sym)
  result[prefix] ||= []; 
  result[prefix] << { suffix => value }
end
#=> { key: [{ a: "value a" }, { b: "value b" }, { c: "value c" }] }

И я бы предложил немного изменить структуру данных, потому что IMO не имеет смысла, чтобы вложенные хэши имели только пару ключ/значение:

my_hash.each_with_object({}) do |(key, value), result| 
  prefix, suffix = key.to_s.split('_').map(&:to_sym)
  result[prefix] ||= {}; 
  result[prefix][suffix] = value
end
#=> { key: { a: "value a", b: "value b", c: "value c" } }

Я согласен с вашим аргументом об изменении структуры данных, но нельзя ли использовать тот же аргумент, чтобы просто вернуть { a: "value a", b: "value b", c: "value c" }?

Cary Swoveland 09.05.2023 21:52

На самом деле я думал, что могут быть и другие префиксы, кроме key, и поэтому подумал, что вложение key имеет смысл.

spickermann 09.05.2023 22:13

Вход

my_hash = {key_a: "value a", key_b: "value b", key_c: "value c"}

Код

new_hash = { key: [] }
my_hash.each_key do |key|
  if key.to_s.start_with?("key_")
    new_key = key.to_s.split("_")[1].to_sym
    new_hash[:key] << { new_key => my_hash[key] }
  end
end
p new_hash

Выход:

{:key=>[{:a=>"value a"}, {:b=>"value b"}, {:c=>"value c"}]}

Если часть key всегда одна и та же, вы можете сделать:

{ key: my_hash.collect { |k, v| { k.to_s.sub('key_', '').to_sym => v } } }

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

def key_prefix(key_sym)
  key_sym[/[^_]*/].to_sym
end
def key_suffix(key_sym)
  key_sym[/[^_]*\z/].to_sym
end

Например,

key_prefix(:key_ccc) #=> :key
key_suffix(:key_ccc) #=> :ccc

См. Символ#[].


Тогда мы можем написать

my_hash = {key_a: "value a", key_b: "value b", key_ccc: "value c"}
{key_prefix(my_hash.first.first)=>my_hash.map {|k,v| { key_suffix(k)=>v}}}
  #=> {:key=>[{:a=>"value a"}, {:b=>"value b"}, {:ccc=>"value c"}]}

Регулярное выражение /[^_]*/ соответствует нулю или более (*) символов (как можно больше) из класса символов [^_], причем последний состоит из всех символов, кроме (^) подчеркивания. Регулярное выражение /[^_]*\z/ такое же, за исключением того, что совпадение должно быть в конце строки (\z — это привязка к концу строки).

Другие вопросы по теме