如何旋转90°包含 ActiveRecord 对象的数组

发布于 2024-11-05 15:51:15 字数 674 浏览 0 评论 0原文

我需要

@my_objects = [ #<MyObject id: 1, title: "Blah1">,
                #<MyObject id: 2, title: "Blah2">,
                #<MyObject id: 3, title: "Blah3">,
                #<MyObject id: 4, title: "Blah4"> ]

将其变成:

@my_objects = { :id => [ 1, 2, 3, 4],
                :title => [ "Blah1" ... ] }

是否有内置方法或某种标准方法?

我只能想象这个

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

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

I have got

@my_objects = [ #<MyObject id: 1, title: "Blah1">,
                #<MyObject id: 2, title: "Blah2">,
                #<MyObject id: 3, title: "Blah3">,
                #<MyObject id: 4, title: "Blah4"> ]

I need to turn it into:

@my_objects = { :id => [ 1, 2, 3, 4],
                :title => [ "Blah1" ... ] }

Is there built in method or some standart approach?

I can imagine only this

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

This question was born while I was thinking on this particular question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沙与沫 2024-11-12 15:51:15

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

a = [[1, "Blah1"], [2, "Blah2"], [3, "Blah3"], [4, "Blah4"]]

然后:

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

替代解决方案:如果相反您只是做了一些平淡无奇的事情,那么可能会不那么棘手并且更容易阅读例如:

i, t = a.transpose
{ :id => i, :title => t }

无论哪种方式:

 => {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]} 

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

Hash[[:id, :title].zip(a.transpose)]

First, use Enumerable#map (something like @o.map { |e| [e.id, e.title] }) to get the ActiveRecord array into a simplified pure Ruby object that looks like this:

a = [[1, "Blah1"], [2, "Blah2"], [3, "Blah3"], [4, "Blah4"]]

Then:

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

Alternate solution: It might be less tricky and easier to read if instead you just did something prosaic like:

i, t = a.transpose
{ :id => i, :title => t }

Either way you get:

 => {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]} 

Update: Tokland has a refinement that's worth citing:

Hash[[:id, :title].zip(a.transpose)]
云归处 2024-11-12 15:51:15

您走在正确的轨道上,这种枢轴没有自定义方法,它应该可以工作,但请记住 ActiveRecord 属性键是字符串:

@my_objects.inject({ }) { |h, c| c.attributes.each { |k,v| (h[k.to_sym] ||= [ ]) << v }; h }

您可以使用 (x ||= [ ]) (x ||= [ ]) < <如果您不太关心它对新手来说是否具有超级可读性,请使用 y 模式来简化一下。

You're on the right track there, there's no custom method for this sort of pivot, and it should work, but remember that ActiveRecord attribute keys are strings:

@my_objects.inject({ }) { |h, c| c.attributes.each { |k,v| (h[k.to_sym] ||= [ ]) << v }; h }

You can use the (x ||= [ ]) << y pattern to simplify that a bit if you're not too concerned with it being super readable to a novice.

妄想挽回 2024-11-12 15:51:15

功能方法(没有每个!):

pairs = @my_objects.map { |obj| obj.attributes.to_a }.flatten(1)   
Hash[pairs.group_by(&:first).map { |k, vs| [k, vs.map(&:second)] }]
#=> {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]}

像往常一样, Facets 允许编写更好的代码;在这种情况下,Enumerable#map_by将避免使用丑陋且复杂的模式group_by+map+map

@my_objects.map { |obj| obj.attributes.to_a }.flatten(1).map_by { |k, v| [k, v] }   
#=> {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]}

Functional approach (no eachs!):

pairs = @my_objects.map { |obj| obj.attributes.to_a }.flatten(1)   
Hash[pairs.group_by(&:first).map { |k, vs| [k, vs.map(&:second)] }]
#=> {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]}

As usual, Facets allows to write nicer code; in this case Enumerable#map_by would avoid using the ugly and convoluted pattern group_by+map+map:

@my_objects.map { |obj| obj.attributes.to_a }.flatten(1).map_by { |k, v| [k, v] }   
#=> {:title=>["Blah1", "Blah2", "Blah3", "Blah4"], :id=>[1, 2, 3, 4]}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文