如何返回按特定列分组的哈希数组

时间:2014-02-11 12:28:19

标签: ruby-on-rails ruby

我有一个展示位置模型,可以在日志中显示员工及其月末位置:

[<Placement id: 1, employee_name: 'John', month: "2014-02-01",position: 2>, 
<Placement id: 2, employee_name: 'John', month: "2014-01-01", position: 2>, 
<Placement id: 3, employee_name: 'Jill', month: "2014-02-01", position: 3>,
<Placement id: 4, employee_name: 'Jill', month: "2014-01-01", position: 1>
<Placement id: 5, employee_name: 'Fred', month: "2014-02-01", position: 1>]

如何返回如下所示的哈希数组:

[
{ month: '2014-02-01', 'John': 2, 'Jill': 3, 'Fred': 1 },
{ month: '2014-01-01', 'John': 2, 'Jill': 1 }
]

4 个答案:

答案 0 :(得分:2)

a = [ <Placement id: 1, employee_name: 'John', month: "2014-02-01",position: 2>, 
      <Placement id: 2, employee_name: 'John', month: "2014-01-01", position: 2>, 
      <Placement id: 3, employee_name: 'Jill', month: "2014-02-01", position: 3>,
      <Placement id: 4, employee_name: 'Jill', month: "2014-01-01", position: 1>
      <Placement id: 5, employee_name: 'Fred', month: "2014-02-01", position: 1> ]

a.group_by(&:month).map  do |month, data|
  hash = {month: month}
  data.each {|placement| hash[placement.employee_name] = placement.position}
  hash
end  

答案 1 :(得分:0)

我建议您进行数据库分组,而不是在代码中进行分组,因为它更有效。

如果您使用mysql,则可以执行以下操作:

(信用到:https://stackoverflow.com/a/14806663/226255

r = Placement.connection.select_all(
 "select date_format(month, '%Y-%m') as monthy,
  GROUP_CONCAT(Concat_Ws('=', employee_name, position)) AS place 
  from placements 
  group by year(month), month(month)")

=> [{"monthy"=>"2014-01", "placement"=>"John=2,Jill=1"},
 {"monthy"=>"2014-02", "placement"=>"John=2,Jill=3,Fred=1"}]

在这里查看sqlfiddle: http://www.sqlfiddle.com/#!2/088e7/1/0

现在,在代码中,转换为与您的问题类似的哈希:

r.map { |m| 
  h = { :month => m["monthy"] }
  m["placement"].split(',').each { |i| 
  k, v = i.split('='); h[k] = v.to_i }; h 
}

=> [{:month=>"2014-01", "John"=>2, "Jill"=>1},
{:month=>"2014-02", "John"=>2, "Jill"=>3, "Fred"=>1}]

答案 2 :(得分:0)

您可以使用Activemodel序列化程序as_json

例如来自doc

user = User.find(1)
user.as_json
# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
#     "created_at" => "2006/08/01", "awesome" => true}

ActiveRecord::Base.include_root_in_json = true

user.as_json
# => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
#                  "created_at" => "2006/08/01", "awesome" => true } }

答案 3 :(得分:0)

试试这个,

 placements = [<Placement id: 1, employee_name: 'John', month: "2014-02-01",position: 2>, 
    <Placement id: 2, employee_name: 'John', month: "2014-01-01", position: 2>, 
    <Placement id: 3, employee_name: 'Jill', month: "2014-02-01", position: 3>,
    <Placement id: 4, employee_name: 'Jill', month: "2014-01-01", position: 1>
    <Placement id: 5, employee_name: 'Fred', month: "2014-02-01", position: 1>]

    placements.map!{|placement| placement.attributes}