Rails - 处理对象数组

时间:2015-10-28 17:05:44

标签: ruby-on-rails arrays

我有一组学生对象(Student.all),每个对象都有一个name和一个class_id

我想找到具有相同class_id的学生,并将他们的名字连接到同一个对象,其他人保持不变。 我的意思是,转过来:

[
  {
    id: 1,
    name: 'Joe',
    class_id: 55
  },
  {
    id: 2,
    name: 'Bill',
    class_id: 55
  },
  {
    id: 3,
    name: 'Moe',
    class_id: 70
  },
  {
    id: 4,
    name: 'Larry',
    class_id: 80
  },
  {
    id: 5,
    name: 'Phill',
    class_id: 80
  }
]

进入这个:

[
  {
    id: 1,
    name: 'Joe/Bill',
    class_id: 55
  },
  {
    id: 3,
    name: 'Moe',
    class_id: 70
  },
  {
    id: 4,
    name: 'Larry/Phill',
    class_id: 80
  }
]

2 个答案:

答案 0 :(得分:3)

假设您只是在创建数组之后(而不是更新数据库),您可以执行以下操作:

arr.group_by{|x| x[:class_id]}
   .values.map{|x| x.reduce{|m,v| m[:name] = "#{m[:name]}/#{v[:name]}";m}}

如果您关心原始阵列,可以进行一些小改动:

arr.group_by{|x| x[:class_id]}
   .values.map{|x| x[1..-1].reduce(x.first){|m,v| m[:name] = "#{m[:name]}/#{v[:name]}";m}}

结果:

[
    {:id=>1, :name=>"Joe/Joe/Bill",      :class_id=>55},
    {:id=>3, :name=>"Moe",               :class_id=>70},
    {:id=>4, :name=>"Larry/Larry/Phill", :class_id=>80}
]

答案 1 :(得分:2)

我的解决方案是使用Enumerable#group_by

students = [...] # the source array
students.group_by(&:class_id)
# => {
  55 => [
    {
      :id       => 1,
      :name     => "Joe",
      :class_id => 55
    },
    {
      :id       => 2,
      :name     => "Bill",
      :class_id => 55
    }
  ],
  70 => [
    {
      :id       => 3,
      :name     => "Moe",
      :class_id => 70
    }
  ],
  80 => [
    {
      :id       => 4,
      :name     => "Larry",
      :class_id => 80
    },
    {
      :id       => 5,
      :name     => "Phil",
      :class_id => 80
    }
  ]
}

# Code in reduce block may need to be changed to fit your demand
students.group_by(&:class_id).reduce([]) do |ret, (k,v)|
  st = v.first
  st.name = v.map(&:name).join('/')
  ret << st
end
# => target