2013-04-10 111 views
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 
     } 
    ] 
} 

我的分組由數組:狀態鍵。我已經這樣做了(它的工作原理):

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

但是,有一個更簡單,更隱祕的一行,可以做同樣的事情?

+1

你不行嗎? – 2013-04-10 08:00:51

回答

2

爲什麼不使用group_by?它完全符合你的需求。

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

我知道有一種方法,我錯過了... – 0xSina 2013-04-10 08:45:00

+1

總是想''group_by'注入''each_with_object'之前,我會說:) – 2013-04-10 08:48:00

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