Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails array group_by

I have a dynamic array of object result from a database query.

USERNAME   choice_indx   legend
USER1        3             4
USER2        0             4
USER3        0             4
USER1        9             2
USER2        9             2
USER3        8             2
USER1        3             1
USER2        9             1
USER3        8             1

Query:

SELECT survey_answers.anonymous_user_id, survey_answers.choice_index, survey_questions.legend 
  FROM `survey_answers` 
  LEFT JOIN surveys ON surveys.id = survey_answers.survey_id 
  LEFT JOIN survey_questions ON survey_questions.id = survey_answers.survey_question_id 
  WHERE (survey_questions.legend IN (1,2,4)) AND (survey_answers.track_id =2) AND (survey_answers.survey_id =2) AND (surveys.survey_type =2)

How can I group this by user and result it like this:

final_array = {
  "USER1" => [[3,4],[9,2],[3,1]], 
  "USER2" => [[0,4],[9,2],[9,1]],
  "USER3" => [[0,4],[8,2],[8,1]]
}

I've tried using group_by in rails, but the result was not the same from what I want. Can anyone lend me a hand? Thanks.

like image 664
user3204760 Avatar asked Jul 25 '26 14:07

user3204760


1 Answers

Assuming objects is an Enumerable of ActiveModel objects with anonymous_user_id, choice_index, and legend attributes, this will do what you want:

objects.map {|obj| obj.values_at(:anonymous_user_id, :choice_index, :legend) }
  .group_by(&:shift)

You can skip the map if instead you use pluck in your ActiveRecord query, e.g.:

MyModel.where(...)
  .pluck(:anonymous_user_id, :choice_index, :legend)
  .group_by(&:shift)

Edit

In reply to your comment, yes it is, although it's not quite as clean:

MyModel.where(...)
  .pluck(:anonymous_user_id, :choice_index, :legend)
  .map {|vals| Hash[ %w[ __key__ c_idx legend ].zip(vals) ] }
  .group_by {|hsh| hsh.delete("__key__") }

Or:

MyModel.where(...)
  .pluck(:anonymous_user_id, :choice_index, :legend)
  .each_with_object(Hash.new {|h,k| h[k] = [] }) do |(key, c_idx, legend), hsh| 
    hsh[key] << { "c_idx" => c_idx, "legend" => legend }
  end
like image 107
Jordan Running Avatar answered Jul 27 '26 04:07

Jordan Running