简体   繁体   中英

Ruby on Rails: flatten arry of hashes & group by key

Let me begin by explaining what I want to do:

I have these models:

"Question"
name:string
belongs_to :Category

"Category"
name:string
has_many :Questions

AgendaItem
title:string
body:string
belongs_to :Category

"Meeting"
has_many :Questions
has_many :AgendaItems

The process is thus: User creates a meeting & adds many questions to it from many different categories (~12 categories, each with 10-20 questions).

I've got that bit working, so I have a Meeting with many Questions on it.

Now, when a User performs a specific action on a meeting called "Finalise" I want to create an AgendaItem (using the Meeting's Questions) for each distinct Category , the :title of the AgendaItem should be the :name of the Category and the :body of it should be all the questions that have been selected under that category

eg: <ul><li>Question1</li><li>Question2</li>...</ul>

I could do this in a nasty big loop (and check whether the current Category of the question I'm on is now different to the previous one & create a new AgendaItem), or use two loops (one to create distinct AgendaItems, and then one to pop the questions into the :body)

But I'm sure there's a better way of doing it, using arrays & inject.

My current code creates an array of hashes (I think) like this:

[{:id=>1, :question=>"Question1"}, {:id=>1, :question=>"Question3"},{:id=>3, :question=>Question10}]

This is the code that does that:

@meeting = Meeting.find <the_id>
array = @meeting.questions.all.map { |q| { id: q.category.id, question: q.name } }

Where :id is the :id of the Category and :question is the :name of the Question

I think I want to end up with this:

[{:id=>1, :question=>"<li>Question1</li><li>Question3</li>"},{:id=>3, :question=><li>Question10</li>}]

Then I can loop over it & create an AgendaItem from the :id (key) and set it's body to be the :question (value).

Try out this:

questions.all.group_by(&:category_id).map { |q|
  {:id => q.first, :question => q.second.each.map { |qn| qn.name }}
}
#output:
#[{:id=>1, :question=>['Question1', 'Question3']},{:id=>3, :question=>['Question10']}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM