Ruby преобразование Array of Arrays в Array of Hashes - PullRequest
0 голосов
/ 04 февраля 2020

Пожалуйста, мне нужна помощь с этим.

В Ruby Если у меня есть этот массив массивов

array = [["a: 1", "b:2"],["a: 3", "b:4"]]

Как я могу получить этот массив хэшей в ruby

aoh = [{:a => "1", :b => "2"},{:a => "3", :b => "4"}]

Ответы [ 3 ]

2 голосов
/ 04 февраля 2020

Обратите внимание, что , как указано в комментариях , это, скорее всего, проблема XY, и вместо преобразования массива лучшим вариантом будет создание начального массива в лучшем виде.

Тем не менее, вы можете сделать это следующим образом:

aoh = array.map { |array| array.to_h { |string| string.split(':').map(&:strip) } }
# => [{"a"=>"1", "b"=>"2"}, {"a"=>"3", "b"=>"4"}]

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

Преобразование в символы можно сделать, добавив следующую строку:

# note that this line will mutate the aoh contents
aoh.each { |hash| hash.transform_keys!(&:to_sym) }
#=> [{:a=>"1", :b=>"2"}, {:a=>"3", :b=>"4"}]
1 голос
/ 04 февраля 2020
array = [["a: 1", "b:2"], ["a: 3", "b:4"]]

array.map do |a|
  Hash[
    *a.flat_map { |s| s.split(/: */) }.
       map { |s| s.match?(/\A\d+\z/) ? s : s.to_sym }
  ]
end
  #=> [{:a=>"1", :b=>"2"}, {:a=>"3", :b=>"4"}]

Регулярное выражение /: */ гласит: «соответствует двоеточие, за которым следует ноль или более (*) пробелов». /\A\d+\z/ читает, "соответствует началу строки (\A), за которым следуют одна или несколько (+) цифр (\d), за которыми следует конец строки (\z).

Шаги следующие: во-первых, элемент arr[0] должен быть передан в блок, переменной блока a присвоено его значение и выполнен расчет блока.

a = array[0]
  #=> ["a: 1", "b:2"]
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "1", "b", "2"] 
c = b.map { |s| s.match?(/\A\d+\z/) ? s : s.to_sym } 
  #=> [:a, "1", :b, "2"]
d = Hash[*c]
  #=> {:a=>"1", :b=>"2"} 

We см. массив ["a: 1", "b:2"], сопоставленный с {:a=>"1", :b=>"2"}. Затем элементу arr[1] передается в блок, переменной блока a присваивается его значение и выполняется вычисление блока.

a = array[1]
  #=> ["a: 3", "b:4"] 
b = a.flat_map { |s| s.split(/: */) }
  #=> ["a", "3", "b", "4"] 
c = b.map { |s| s.match?(/\d/) ? s : s.to_sym } 
  #=> [:a, "3", :b, "4"] 
d = Hash[*c]
  #=> {:a=>"3", :b=>"4"} 

Оператор splat (*) заставляет Hash[*c] быть оценен как:

Hash[:a, "3", :b, "4"]

См. Ха sh :: [] .

0 голосов
/ 04 февраля 2020

L oop через ваши элементы, l oop через его элементы, создайте новый массив:

array.map do |items| 
  items.map do |item| 
    k,v = item.split(":", 2)
    { k.to_sym => v } 
  } 
} 

Обратите внимание, что мы используем map вместо each, который вернет массив.

...