Как преобразовать массив, подобный этому ["Джон, Доу, 11222019", "Марк, Кинг, 11232019", "Угол, Дарма, 11242019"], в массив хэшей Ruby - PullRequest
0 голосов
/ 21 февраля 2019

Как преобразовать массив:

["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]

в массив хэшей, используя Ruby:

[
  { :name => "John Doe", :number => 11222019 },
  { :name => "Mark King", :number => 11232019 },
  { :name => "Angle Darma", :number => 11242019 },
] 

Большое спасибо!

Ответы [ 5 ]

0 голосов
/ 21 февраля 2019
arr = ["John,Doe,11222019", "Mark,King,11232019",
       "Angle,Darma,11242019"]

arr.map do |s|
  {name: s[/.+(?=,)/].tr(',',' '), number: s[/\d+/].to_i}
end
  #=> [{:name=>"John Doe",    :number=>11222019},
  #    {:name=>"Mark King",   :number=>11232019},
  #    {:name=>"Angle Darma", :number=>11242019}] 

Шаги следующие. Enumerable # map передает первый элемент arr в блок, и переменная блока s устанавливается равной его значению:

s = arr.first
  #=> "John,Doe,11222019"

Затем выполняются вычисления блока:

a = s[/.+(?=,)/]
  #=> "John,Doe"

При этом используется метод String # [] с регулярным выражением /.+(?=,)/.(?=,) - это позитивный прогноз , который требует, чтобы за совпадением сразу следовала запятая.Поскольку совпадения по умолчанию жадные , предпросмотр соответствует последней запятой в s.

b = a.tr(',',' ')
  #=> "John Doe"

При этом используется метод String # tr .В качестве альтернативы можно использовать a.sub(',',' ').

c = s[/\d+/]
  #=> "11222019" 
d = c.to_i
  #=> 11222019 

Затем блок возвращает:

{ name: c, number: d }
  #=> {:name=>"11222019", :number=>11222019} 

, то есть объект, на который отображается s.Оставшиеся два значения arr передаются в блок и выполняются аналогичные вычисления.

0 голосов
/ 21 февраля 2019
arr = ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]

arr.map do |item|
  chunks = item.split(",")
  {name: chunks[0...-1].join(" "), number: chunks[-1]}
end

Индексирование по [0 ...- 1] позволяет вам иметь переменное количество элементов в части имени (отчество или фамилия из двух частей), что является довольно распространенным явлением.

0 голосов
/ 21 февраля 2019

Вы можете сделать это просто, как показано ниже,

array.map { |x| [:name, :number].zip(x.sub(',', ' ').split(',')).to_h }

# => [{:name=>"John Doe", :number=>11222019}, {:name=>"Mark King", :number=>11232019}, {:name=>"Angle Darma", :number=>11242019}] 
0 голосов
/ 21 февраля 2019

Опция с использованием Ruby 2.6.1 Object # затем :

ary = ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]

ary.map { |s| s.split(',').then{ |a| {name: a.first(2).join(' ') , number: a.last.to_i } } }

Для Ruby 2.5.2 Object # yield_self :

ary.map { |s| s.split(',').yield_self{ |a| {name: a.first(2).join(' ') , number: a.last.to_i } } }

Оба возвращаются:

#=> [{:name=>"John Doe", :number=>11222019}, {:name=>"Mark King", :number=>11232019}, {:name=>"Angle Darma", :number=>11242019}]
0 голосов
/ 21 февраля 2019

a = ["Джон, Доу, 11222019", "Марк, Кинг, 11232019", "Угол, Дарма, 11242019"]

Как-то так

a.map do |f|
  f = f.split(',')
  { name: "#{f[0]} #{f[1]}", number: f[2].to_i }
end
...