2017-07-07 66 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

相关问题