London
London

Reputation: 15274

Complex map by objects property in ruby

I'm trying to create different kind of structure from the array I currently have in my code.

I've got an array of objects (active directory objects) so lets say i got a from db :

a = [o1,o2,o3,o4,o5]

My object has property source_id and name which are the relevant properties.

I want to create structure like this (I want hash) from the data I have in my array :

objects = Hash.new { |hash, key| hash[key] = [] }

And this would be one example of how to put the data inside new structure:

a.each do |ob|
  objects[ob.source_id] << {
   :new => '',
   :name => {:unformated => ob.name, :formatted => ob.format(:name)}
  }
end

I'm trying to replicate the same structure and it's not working out in my case :

a.group_by(&:source_id).map do |k,v|
 {
   k=> {
         {
           :new => '',
           :name => {:unformated => v.name, :formatted => ob.format(:name)}
         }
       }
 }
end.reduce(:merge)

This is the error I get :

! #<NoMethodError: undefined method `name' for #<Array:0xae542b4>>

Upvotes: 0

Views: 672

Answers (2)

Doydle
Doydle

Reputation: 921

Heres a one liner to do the same

new_hash = a.each_with_object({}) { |o, hash| hash[o.source_id] = {:new => '', :unformatted => o.name, :formatted => o.format(:name)} }

This does require ruby 1.9.3 though

Upvotes: 0

Aaron Cronin
Aaron Cronin

Reputation: 2103

With group_by your values in the a.group_by(&:source_id).map are going to be arrays of elements sharing the same source_id and not individual elements.

The following code may do what you wish:

a.group_by(&:source_id).map do |k,v|
 {
   k => v.map do |e|
       {
         :new => '',
         :name => {:unformated => e.name, :formatted => e.format(:name)}
       }
   end
 }
end.reduce(:merge)

Upvotes: 1

Related Questions