Использование массива строк для проверки наличия вложенного свойства в хэше - PullRequest
0 голосов
/ 26 апреля 2018

Рассмотрим массив свойств, которые могут существовать во вложенном хэше:

property_selector = ['component_styles', 'styles', 'background' ,'color']

Возможны следующие вложенные хэши:

object_to_search_containing_property = {
    some_attr: 'blah',
    component_styles: {
        styles: {
            background: {
                color: 'fff'
            }
        }
    }
}

object_to_search_not_containing_property = {
    some_attr: 'blah',
    component_styles: {

    }
}

Может ли быть способ перебрать property_selector для поиска по этим объектам, проверяя каждый уровень вложения свойств?

Есть ли в Ruby что-то похожее на:

property_selector.each do |property|
    object[property][next_property] ... [property.length - 1]
end

Обновление

Извините, что не упомянул ранее, но я использую версию Ruby 2.2.3 .

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Если вы ищете способ получить значения property_selector, тогда hashie gem может быть полезным. Есть много вещей, которые он может сделать, поэтому я призываю всех проверить это. В этом случае можно использовать расширение DeepFind . Вот пример из документации:

require 'hashie'

user = {
  name: { first: 'Bob', last: 'Boberts' },
  groups: [
    { name: 'Rubyists' },
    { name: 'Open source enthusiasts' }
  ]
}

user.extend Hashie::Extensions::DeepFind

user.deep_find(:name)   #=> { first: 'Bob', last: 'Boberts' }
user.deep_detect(:name) #=> { first: 'Bob', last: 'Boberts' }

user.deep_find_all(:name) #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'Open source enthusiasts']
user.deep_select(:name)   #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'Open source enthusiasts']

Может выполнять поиск по любому перечисляемому, содержащемуся в хэше, объектам с указанным ключом.

И на основе .travis.yml gem поддерживает mri >= 2.0.0, jruby-9.0.5.0 и rbx-3

0 голосов
/ 27 апреля 2018

То, что я здесь написал, неверно. Если позволит время, я исправлю это, но пока не обращайте внимания.

0 голосов
/ 26 апреля 2018

Вы на Ruby 2.3+? Попробуйте Hash#dig:

object_to_search_containing_property.dig(*property_selector) # => "fff"
object_to_search_not_containing_property.dig(*property_selector) # => nil

Единственная ошибка в том, что элементы вашего массива селекторов свойств являются строками, но вы создаете вложенный объект с помощью символьных ключей. Вместо этого определите свой массив селектора свойств, как показано выше, для работы приведенного выше кода:

property_selector = [:component_styles, :styles, :background, :color]

Или, если вы не можете контролировать, как определяется этот массив, вы можете преобразовать его на лету:

object.dig(*property_selector.map(&:to_sym))

Вот портативный метод:

def dig(object, *keys)
  keys.each do |key|
    break unless object.respond_to?(:[])

    object = object[key]
  end

  object
end

dig(object_to_search_containing_property, *property_selector) # => "fff"
dig(object_to_search_not_containing_property, *property_selector) # => nil

То же предостережение о массиве селектора свойств применимо и здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...