0

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

[
    [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 键对数组进行分组。我已经这样做了(它有效):

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

但是,有没有一种更简单、不那么神秘的单线可以做同样的事情?

4

2 回答 2

2

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

a.group_by {|b| b[:status] }
于 2013-04-10T08:29:46.477 回答
1

这不是一个足够常见的操作来保证一个内置的描述方法,但我会稍微调整你的行。

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

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

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
于 2013-04-10T08:17:24.597 回答