2017-07-07 102 views
2

我有哈希以下形式的數組:如果密鑰相同,如何將哈希數組分成不同的數組?

{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>5.0} 
{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.8499999999999996} 
{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>0.0} 
{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.4} 

基本上我想是數組包含的關鍵beneficiary_document相同的值陣列分開的,所以在這個例子中我會人希望兩個陣列,一個包含:

{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>5.0} 
{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>0.0} 

和含

{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.4} 
{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.8499999999999996} 

我怎樣授予這一個又一個?

非常感謝您的閱讀。

+0

http://blog.jayfields.com/2008/03/ruby-inject.html –

+0

當你給你的所有輸入和輸出應該是有效的Ruby對象的例子。 (如果不是,那麼有些讀者會倒下。)這意味着你應該寫'[{...},..,{...}]'。此外,爲每個輸入分配一個變量也很有幫助(例如'arr = [{「user_id」=> 2,..},... {「user_id」=> 3,...}]'。讀者可以在回答和評論中引用這些變量,而無需定義它們,還可以將示例縮減爲最基本的要素,並使用鍵和值的縮寫名稱(部分是爲了避免讀者需要水平滾動讀取你的代碼) –

回答

6

考慮:

tst=[ 
{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>5.0}, 
{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.84}, 
{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>0.0}, 
{"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.4} 
] 

您可以使用.group_by獲得通過的關鍵要素的哈希值。在這種情況下,使用傳遞給塊的密鑰["beneficiary_document"],您將通過該密鑰獲得數組散列值 - 在這種情況下爲兩個。

你可以這樣做:

tst.group_by { |h| h["beneficiary_document"] } 
# {"43991028"=>[{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>5.0}, {"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>0.0}], "71730550"=>[{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.84}, {"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.4}]} 

要看到它漂亮的印刷

require "pp" 
PP.pp(tst.group_by {|h| h["beneficiary_document"] },$>,120) 
{"43991028"=> 
    [{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>5.0}, 
    {"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"43991028", "calification_by_qualifier"=>0.0}], 
"71730550"=> 
    [{"user_id"=>2, "user_name"=>"Pepo", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.84}, 
    {"user_id"=>3, "user_name"=>"Carlos", "beneficiary_document"=>"71730550", "calification_by_qualifier"=>3.4}]} 

您也可以實現與返回數組作爲default procedure哈希相同的結果,然後調用.map高於tst並通過該密鑰將散列推入陣列中:

h=Hash.new { |h,k| h[k]=[] } 
tst.map { |eh| h[eh["beneficiary_document"]].push(eh) } 

或者是合併成一個單一的語句:

tst.each_with_object(Hash.new { |h,k| h[k]=[] }) { |g,h| 
    h[g["beneficiary_document"]].push(g)} 

這三種方法創建相同的哈希值。第一個,.group_by,是最簡單的。

+1

比我所在的地方要好得多,我不得不刪除我的地址,很好! – jvillian

3

這裏有三種方法通過構造一個散列並提取值來獲得所需的結果。

arr = [{"id"=>2, "name"=>"Pepo", "doc"=>"43991028", "cal"=>5.0}, 
     {"id"=>2, "name"=>"Pepo", "doc"=>"71730550", "cal"=>3.8}, 
     {"id"=>3, "name"=>"Carlos", "doc"=>"43991028", "cal"=>0.0}, 
     {"id"=>3, "name"=>"Carlos", "doc"=>"71730550", "cal"=>3.4}] 

#1

這使用的Hash::new,其包括當被執行h[k]時調用,對於沒有密鑰k散列h的塊的形式。

arr.each_with_object(Hash.new { |h,k| h[k]=[] }) { |g,h| h[g["doc"]] << g }. 
    values 
    #=> [[{"id"=>2, "name"=>"Pepo", "doc"=>"43991028", "cal"=>5.0}, 
    #  {"id"=>3, "name"=>"Carlos", "doc"=>"43991028", "cal"=>0.0}], 
    # [{"id"=>2, "name"=>"Pepo", "doc"=>"71730550", "cal"=>3.8}, 
    #  {"id"=>3, "name"=>"Carlos", "doc"=>"71730550", "cal"=>3.4}]] 

#2

這相當於#1。

arr.each_with_object({}) { |g,h| (h[g["doc"]] ||= []) << g }. 
    values 

#3

這使用的Hash#update(又名merge!)的形式,其使用的塊(這裏{ |_,o,n| o+n }),以確定存在於被合併兩個散列密鑰的值。請參閱文檔瞭解確定值塊的三個變量的定義。

arr.each_with_object({}) { |g,h| h.update(g["doc"]=>[g]) { |_,o,n| o+n } }. 
    values 
+0

前兩個真的很有趣,第三個產生'{nil => [原始列表]},因爲沒有在默認散列表中輸入密鑰 – dawg

+0

@dawg,請仔細檢查#3,它不使用默認散列表 –

+0

我有一個小小的腳本,用你的例子'arr',然後剪切並粘貼你的#1,#2, #3。前兩個創建正確的輸出;#3:'{nil => [{「id」=> 2,「name」=>「Pepo」,「doc」=>「43991028」,「cal」=> 5.0},{「id」= > 2,「name」=>「Pepo」,「doc」=>「71730550」,「cal」=> 3.8},{「id」=> 3,「name」=>「Carlos」,「doc」 >「43991028」,「cal」=> 0.0},{「id」=> 3,「name」=>「Carlos」,「doc」=>「71730550」,「cal」=> 3.4}]}。 Ruby 2.4.1。我刪除了'.values'部分的所有三個... – dawg

相關問題