преобразовать массив объектов (созданный из OpenStruct) в массив значений - PullRequest
0 голосов
/ 01 октября 2018

Я изучаю рубин и играю с образцом данных.Я преобразовал следующий хеш в массив объектов следующим образом.

class Openstruct
  require 'JSON'
  require 'ostruct'

  HASH = {
    items: [
      {
        health: [
          {
            goal: [
              {
                activity: [
                  {
                    id: "1A"
                  },
                  {
                    id: "2A"
                  }
                ],
                id: "GA"
              }
            ],
            activity: [
              {
                id: "1B"
              },
              {
                id: "2B"
              }
            ],
            id: "GB"
          }
        ],
        goal: [
          {
            activity: [
              {
                id: "1C"
              },
              {
                id: "2C"
              },
            ],
            id: "3c"
          }
        ],
        createdAt: "2018-01-01",
        updatedAt: "2018-01-01",
        id: "DA"
      }
    ],
  }

  def self.all
    json = HASH.to_json
    JSON.parse(json, object_class: OpenStruct)
  end

end

Выше выдает мне следующий результат

#<OpenStruct items=
  [#<OpenStruct health=
      [#<OpenStruct goal=
        [#<OpenStruct activity=
          [#<OpenStruct id="1A">, #<OpenStruct id="2A">], id="GA">], 
          activity=[#<OpenStruct id="1B">, #<OpenStruct id="2B">], id="GB">], 
          goal=[#<OpenStruct activity=[#<OpenStruct id="1C">, #<OpenStruct id="2C">], id="3c">], 
          createdAt="2018-01-01", 
          updatedAt="2018-01-01", 
          id="DA">]>

Однако я хочу преобразовать массив объектов, имеющих идентификаторы, в массивзначения идентификаторов.например, [#<OpenStruct id="1A">, #<OpenStruct id="2A">] -> ["1A", "2A"].поэтому я хочу, чтобы окончательный результат был следующим:

#<OpenStruct items=
  [#<OpenStruct health=
      [#<OpenStruct goal=
        [#<OpenStruct activity=
          ["1A","2A"], id="GA">], 
          activity=["1B", 2B"], id="GB">], 
          goal=[#<OpenStruct activity=["1C","2C"], id="3c">], 
          createdAt="2018-01-01", 
          updatedAt="2018-01-01", 
          id="DA">]>

Кто-нибудь знает, как это сделать?

1 Ответ

0 голосов
/ 01 октября 2018

Вам придется рекурсивно проверять дочерний узел, пока не найдете OpenStruct только с элементом :id.Ниже приведен рабочий код для ваших примеров данных.

def self.convert_struct_id(os)
  # Get possible attributes of any open_struct
  attributes = os.to_h.keys

  # Only get id_value if :id is the only attribute of open_struct
  if attributes.length == 1 && attributes.first == :id
    id_value = os.send(:id)
    return id_value
  end

  # Iterate through attributes
  attributes.each do |attr|
    # Get child elements
    data = os.send(attr)
    case data
    when OpenStruct
      convert_struct_id(data)
    when Array
      # Recursively process for child node
      data.map! { |d| convert_struct_id(d) }
    end
  end
  return os
end

Ваш self.all метод будет выглядеть следующим образом

def self.all
  json = HASH.to_json
  os = JSON.parse(json, object_class: OpenStruct)
  res = convert_struct_id(os)
end

Результат:

=> #<OpenStruct items=[#<OpenStruct health=[#<OpenStruct goal=[#<OpenStruct activity=["1A", "2A"], id="GA">], activity=["1B", "2B"], id="GB">], goal=[#<OpenStruct activity=["1C", "2C"], id="3c">], createdAt="2018-01-01", updatedAt="2018-01-01", id="DA">]>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...