1

I'm working with an array of OpenStruct objects which looks like this:

a=[<OpenStruct name="test1", x="6", id="1">,<OpenStruct name="test2", x="5", id="2"><OpenStruct name="test1", x="8", id="3">...] 

I would like to group the OpenStruct objects having the same name, something like this:

a=[<OpenStruct name="test1",x=["6","8"], id=["1","3"]>,<OpenStruct name="test2", x="5", id="2">] 

How can I do that?

2
  • 2
    did you look at groupBy? It seems useful :-) Commented Sep 23, 2013 at 13:08
  • @JanDvorak groupBy groups the elements, not their attributes. Commented Sep 23, 2013 at 13:58

2 Answers 2

1

You could use group_by and map methods. I think the code is self explanatory.

a = [ OpenStruct.new(name: "test1", x: "6", id: "1"), OpenStruct.new(name: "test2", x: "5", id: "2"), OpenStruct.new(name: "test1", x: "8", id: "3") ] a.group_by(&:name).map do |name, as| OpenStruct.new( name: name, x: as.map(&:x), id: as.map(&:id) ) end # => [#<OpenStruct name="test1", x=["6", "8"], id=["1", "3"]>, #<OpenStruct name="test2", x=["5"], id=["2"]>] 
Sign up to request clarification or add additional context in comments.

Comments

0

Something like this should work:

a = [ OpenStruct.new(name: "test1", x: "6", id: "1"), OpenStruct.new(name: "test2", x: "5", id: "2"), OpenStruct.new(name: "test1", x: "8", id: "3") ] a.each_with_object({}) { |o, h| h[o.name] ||= OpenStruct.new(name: o.name, x: [], id: []) h[o.name][:x] << o.x h[o.name][:id] << o.id }.values #=> [#<OpenStruct name="test1", x=["6", "8"], id=["1", "3"]>, #<OpenStruct name="test2", x=["5"], id=["2"]>] 

Note that the x and id attributes for test2 are also converted to arrays. This is usually preferred.

It might be good idea to rename the attributes to indicate an array, i.e. ids instead of id.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.