TypeError - нет неявного преобразования Symbol в целое число - PullRequest
0 голосов
/ 27 августа 2018

Hash

data = {
  :recordset => {
    :row => {
      :property => [
        {:name => "Code",     :value => "C0001"}, 
        {:name => "Customer", :value => "ROSSI MARIO"}
      ]
    }
  },
  :@xmlns => "http://localhost/test"
}

Используемый код

result = data[:recordset][:row].each_with_object([]) do |hash, out|
           out << hash[:property].each_with_object({}) do |h, o|
                    o[h[:name]] = h[:value]
                  end
         end

Я не могу получить следующий вывод:

[{"Code"=>"C0001", "Customer"=>"ROSSI MARIO", "Phone1"=>"1234567890"}

Сообщение об ошибке:

TypeError нет неявного преобразования Symbol в целое число

Работает корректно в случае нескольких записей

data = {
  :recordset => {
    :row => [{
      :property => [
        {:name => "Code",     :value => "C0001"},
        {:name => "Customer", :value => "ROSSI MARIO"},
        {:name => "Phone1",   :value => "1234567890"}
      ]
    }, {
      :property => [
        {:name => "Code",     :value => "C0002"},
        {:name => "Customer", :value => "VERDE VINCENT"},
        {:name => "Phone1",   :value => "9876543210"},
        {:name => "Phone2",   :value => "2468101214"}
      ]
    }]
  },
  :@xmlns => "http://localhost/test"
}

Используемый код

data.keys
#=> [:recordset, :@xmlns] 

data[:recordset][:row].count
#=> 2   # There are 2 set of attribute-value pairs


result = data[:recordset][:row].each_with_object([]) do |hash, out|
           out << hash[:property].each_with_object({}) do |h, o|
                    o[h[:name]] = h[:value]
                  end
         end
#=> [
#   {"Code"=>"C0001", "Customer"=>"ROSSI MARIO", "Phone1"=>"1234567890"},
#   {"Code"=>"C0002", "Customer"=>"VERDE VINCENT", "Phone1"=>"9876543210", "Phone2"=>"2468101214"}
# ] 

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

В первом случае data[:recordset][:row] - это не массив, а хэш, поэтому при его повторении переменная hash становится массивом:

[:property, [{:name=>"Code", :value=>"C0001"}, {:name=>"Customer", :value=>"ROSSI MARIO"}]]

Во втором случае это массив, а не хэш, поэтому при его повторении он становится хешем:

{:property=>[{:name=>"Code", :value=>"C0001"}, {:name=>"Customer", :value=>"ROSSI MARIO"}, {:name=>"Phone1", :value=>"1234567890"}]}

Вы всегда предполагаете, что это второй формат. Вы можете принудительно преобразовать его в массив, а затем сгладить на 1 уровень, чтобы обработать оба экземпляра одинаково:

result = [data[:recordset][:row]].flatten(1).each_with_object([]) do |hash, out|
  out << hash[:property].each_with_object({}) do |h, o|
    o[h[:name]] = h[:value]
  end
end

# => [{"Code"=>"C0001", "Customer"=>"ROSSI MARIO"}] # result from example 1
# => [{"Code"=>"C0001", "Customer"=>"ROSSI MARIO", "Phone1"=>"1234567890"},
#     {"Code"=>"C0002", "Customer"=>"VERDE VINCENT",
#      "Phone1"=>"9876543210", "Phone2"=>"2468101214"}] # result from example 2

Заманчиво попытаться использовать Kernal#Array() вместо [].flatten(1), но вы должны помнить, что Hash реализует to_a для возврата вложенного массива ключей и значений, поэтому Kernal#Array() не делает не работает так, как вы хотели бы:

Array(data[:recordset][:row]) # using the first example data
# => [[:property, [{:name=>"Code", :value=>"C0001"}, {:name=>"Customer", :value=>"ROSSI MARIO"}]]]
0 голосов
/ 27 августа 2018

Вы можете создать массив, если это не массив для нормализации ввода перед его обработкой.

info = data[:recordset][:row]
info = [info] unless info.is_an? Array
result = info.each_with_object([]) do ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...