如何使用ActiveRecord对象旋转90°数组

fl0*_*00r 3 ruby activerecord ruby-on-rails

我有

@my_objects = [ #<MyObject id: 1, title: "Blah1">,
                #<MyObject id: 2, title: "Blah2">,
                #<MyObject id: 3, title: "Blah3">,
                #<MyObject id: 4, title: "Blah4"> ]
Run Code Online (Sandbox Code Playgroud)

我需要把它变成:

@my_objects = { :id => [ 1, 2, 3, 4],
                :title => [ "Blah1" ... ] }
Run Code Online (Sandbox Code Playgroud)

是内置方法还是一些标准方法?

我只能想象这个

@my_objects.inject({}){ |h, c| c.attributes.each{ |k,v| h[k] ||= []; h[k] << v }; h }
Run Code Online (Sandbox Code Playgroud)

这个问题是在我思考这个特定问题的时候诞生的

Dig*_*oss 5

首先,使用Enumerable #map(类似的东西@o.map { |e| [e.id, e.title] })将ActiveRecord数组转换为简化的纯Ruby对象,如下所示:

a = [[1, "Blah1"], [2, "Blah2"], [3, "Blah3"], [4, "Blah4"]]
Run Code Online (Sandbox Code Playgroud)

然后:

a.transpose.zip([:id, :title]).inject({}) { |m, (v,k)| m[k] = v; m }
Run Code Online (Sandbox Code Playgroud)

替代解决方案: 它可能不那么棘手,更容易阅读,只是你做了一些平凡的事情:

i, t = a.transpose
{ :id => i, :title => t }
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,你得到:

 => {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]} 
Run Code Online (Sandbox Code Playgroud)

更新: Tokland有一个值得引用的改进:

Hash[[:id, :title].zip(a.transpose)]
Run Code Online (Sandbox Code Playgroud)