我有一个来自数据库查询的动态数组对象结果。
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
查询:
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)
如何按用户对此进行分组,结果如下:
final_array = {
"USER1" => [[3,4],[9,2],[3,1]],
"USER2" => [[0,4],[9,2],[9,1]],
"USER3" => [[0,4],[8,2],[8,1]]
}
我尝试在rails中使用group_by,但结果与我想要的结果不一样。任何人都可以帮我一把吗?感谢。
答案 0 :(得分:3)
假设objects
是包含anonymous_user_id
,choice_index
和legend
属性的ActiveModel对象的可枚举对象,这将执行您想要的操作:
objects.map {|obj| obj.values_at(:anonymous_user_id, :choice_index, :legend) }
.group_by(&:shift)
如果您在ActiveRecord查询中使用map
,则可以跳过pluck
,例如:
MyModel.where(...)
.pluck(:anonymous_user_id, :choice_index, :legend)
.group_by(&:shift)
在回复你的评论时,是的,虽然它不是那么干净:
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__") }
或者:
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
答案 1 :(得分:1)
假设查询的结果是data_hash
(哈希数组),那么以下内容将为您提供所需的结果:
data_hash = [{ 'USERNAME' => 'USER1', 'choice_indx' => 3, 'legend' => 4 },
{ 'USERNAME' => 'USER2', 'choice_indx' => 0, 'legend' => 4 },
{ 'USERNAME' => 'USER3', 'choice_indx' => 0, 'legend' => 4 },
{ 'USERNAME' => 'USER1', 'choice_indx' => 9, 'legend' => 2 },
{ 'USERNAME' => 'USER2', 'choice_indx' => 9, 'legend' => 2 },
{ 'USERNAME' => 'USER3', 'choice_indx' => 8, 'legend' => 2 },
{ 'USERNAME' => 'USER1', 'choice_indx' => 3, 'legend' => 1 },
{ 'USERNAME' => 'USER2', 'choice_indx' => 9, 'legend' => 1 },
{ 'USERNAME' => 'USER3', 'choice_indx' => 8, 'legend' => 1 }]
final_array = Hash.new{|h,k|h[k]=[]}
data_hash.each do |data|
final_array[data['USERNAME']] << [data['choice_indx'], data['legend']]
end
p final_array
# => {"USER1"=>[[3, 4], [9, 2], [3, 1]], "USER2"=>[[0, 4], [9, 2], [9, 1]], "USER3"=>[[0, 4], [8, 2], [8, 1]]}
答案 2 :(得分:1)
我不相信有 rails方式来做这件事,但是你可以用红宝石
# create hash with a empty array for each username
results = Hash[@query.pluck(:username).map { |username| [username, []] }]
@query.each { |data| results[data.username] << [data.choice_idx,
data.legend] }