4

I have array of nested hash that is,

@a = [{"id"=>"5", "head_id"=>nil,
         "children"=>
             [{"id"=>"19", "head_id"=>"5",
                 "children"=>
                     [{"id"=>"21", "head_id"=>"19", "children"=>[]}]},
             {"id"=>"20", "head_id"=>"5",
                 "children"=>
                     [{"id"=>"22", "head_id"=>"20", "children"=>[]}, {"id"=>"23"}]
             }]
     }]

I need array of all values which have key name 'id'. like @b = [5,19,21,20,22,23] I have already try this '@a.find { |h| h['id']}`. Is anyone know how to get this?

Thanks.

2
  • This also works: @a.to_s.scan(/(?<=\"id\"=>\")\d+/).map(&:to_i) #=> [5, 19, 21, 20, 22, 23]. Commented Dec 23, 2014 at 18:37
  • @CarySwoveland great Its is working like charm. Thanks Commented Dec 24, 2014 at 5:46

2 Answers 2

5

You can create new method for Array class objects.

class Array
  def find_recursive_with arg, options = {}
    map do |e|
      first = e[arg]
      unless e[options[:nested]].blank?
        others = e[options[:nested]].find_recursive_with(arg, :nested => options[:nested])
      end
      [first] + (others || [])
    end.flatten.compact
  end
end

Using this method will be like

@a.find_recursive_with "id", :nested => "children"
Sign up to request clarification or add additional context in comments.

3 Comments

I can't seem to find how does map work here. If you can give an explanation it would be nice.
plus one for the solution
map is similar to each difference is that each returns array on which you have called it, but map replace e element with last line in this example [first] + (others || []) will be replaced with every element in array. see also Ruby map
4

It can be done like this, using recursion

def traverse_hash
  values = []
  @a = [{"id"=>"5", "head_id"=>nil,
     "children"=>
         [{"id"=>"19", "head_id"=>"5",
             "children"=>
                 [{"id"=>"21", "head_id"=>"19", "children"=>[]}]},
         {"id"=>"20", "head_id"=>"5",
             "children"=>
                 [{"id"=>"22", "head_id"=>"20", "children"=>[]}, {"id"=>"23"}]
         }]
 }] 
 get_values(@a)
end

def get_values(array)   
  array.each do |hash|        
    hash.each do |key, value|
      (value.is_a?(Array) ? get_values(value) : (values << value)) if key.eql? 'id'
    end
  end    
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.