Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using array of strings to check for existence of nested property in hash

Tags:

ruby

Consider an array of properties that could exist within a nested hash:

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

With the following nested hashes being possibilites:

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: {

    }
}

Might there be a way to iterate through property_selector to search through these objects checking each level of the property nesting?

Is there anything in Ruby that does something akin to:

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

Updates

Apologies for not mentioning before but I am using Ruby version 2.2.3.

like image 695
Xenyal Avatar asked Nov 24 '25 09:11

Xenyal


1 Answers

Are you on Ruby 2.3+? Try Hash#dig:

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

The only bugaboo is that the elements of your property selector array are strings, but you're building your nested object with symbol keys. Define your property selector array like this instead for the above code to work:

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

Or, if you don't have control over how that array is defined, you can transform it on the fly:

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

Here's a portable method:

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

The same caveat about the property selector array applies here as well.

like image 85
mwp Avatar answered Nov 27 '25 17:11

mwp