基于特定键组合散列数组

时间:2013-04-10 07:59:50

标签: ruby hash

我需要一个基于每个哈希的特定键的哈希数组。例如,采取这个:

[
    [0] {
        :status => "pending",
             :x => 1,
             :y => 2
    },
    [1] {
        :status => "pending",
             :x => 33,
             :y => 74
    },
    [2] {
        :status => "done",
             :x => 33,
             :y => 74
    }
]

我需要将其转换为:

{
    "pending" => [
        [0] {
            :status => "pending",
                 :x => 1,
                 :y => 2
        },
        [1] {
            :status => "pending",
                 :x => 33,
                 :y => 74
        }
    ],
       "done" => [
        [0] {
            :status => "done",
                 :x => 33,
                 :y => 74
        }
    ]
}

我正在通过以下方式对数组进行分组:status key。我做了这个(它有效):

a.inject({}) {|a, b| (a[b[:status]] ||= []) << b; a }

但是,是否有更简单,不那么神秘的单行内容可以做同样的事情?

2 个答案:

答案 0 :(得分:2)

为什么不使用group_by?它完全符合您的需求。

a.group_by {|b| b[:status] }

答案 1 :(得分:1)

保证内置描述性方法并不是一种常见的操作,但我会略微调整你的行。

而不是使用#inject(),如何使用#each_with_object()?它更适合在迭代中传递相同的对象,因为它正是它所做的 - 它也比“注入”IMO更具描述性。

这具有从块的末尾删除; a的额外好处:这是使用inject在每次迭代之间传递相同对象的问题。因此,最后一行变为(带有一些变量名称调整):

ary.each_with_object({}) {|e, obj| (obj[e[:status]] ||= []) << e }

each_with_object的返回值是正在构建的哈希,因此您可以将上述内容分配给变量,或者从方法中返回。

最后,如果您希望它在您的应用程序中更具描述性,请将该行包装在 描述性的方法中:

def index_with_status(ary)
    ary.each_with_object({}) {|e, obj| (obj[e[:status]] ||= []) << e }
end