Преобразовать массив объектов (созданный из OpenStruct) в массив значений

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

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">]>

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

Это самый высокий хэш, который я видел за долгое время. В реальной жизни подумайте о том, чтобы сделать некоторые сокращения, например, сделать одну следующую строку: { activity: [{ id: "1A" }, { id: "2A" }], id: "GA" } (или даже goal: [{ activity: [{ id: "1A" }, { id: "2A" }], id: "GA" }],). Разве это не так ясно? Полезно иметь возможность просматривать весь объект без необходимости прокручивать его по вертикали (и тем более по горизонтали). Конечно, если заплатить строчкой кода ...

Cary Swoveland 01.10.2018 22:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
719
1

Ответы 1

Вам нужно будет рекурсивно проверять дочерний узел, пока вы не найдете 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">]>

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