如果键相等,如何将哈希数组分离到不同的数组中?

时间:2022-09-03 21:44:11

I've got an array of hashes in the following form:

我有一个散列数组,形式如下:

{"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}

basically i want to separate that array into arrays that contain the same value for the key beneficiary_document, so for this example i'd expect two arrays, one containing:

基本上,我想把这个数组分割成数组,数组中包含与key crediary_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}

and another one containing

和另一个包含

{"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}

How can i grant this?

我怎么能同意呢?

Thanks a lot for reading.

非常感谢您的阅读。

2 个解决方案

#1


6  

Given:

考虑到:

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}
]

You can use .group_by to get a hash of elements by key. In this case, use the key ["beneficiary_document"] passed to the block and you will get a hash of arrays by that key -- two in this case.

您可以使用.group_by来通过键获取元素的散列。在本例中,使用传递给块的键["有权受益者_document"],您将通过该键获得数组的散列——在本例中是2。

You can do:

你能做什么:

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}]}

To see it pretty printed:

看到它印得很漂亮:

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}]}

You can also achieve the same result with a hash that returns an array as a default procedure, then call .map over tst and push the hash into the array by that key:

您还可以使用一个作为默认过程返回数组的散列实现相同的结果,然后通过tst调用.map并通过该键将散列推入数组:

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

Or, combine that into a single statement:

或者,把它合并成一句话:

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

All three methods create identical hashes. The first, .group_by, is the easiest.

这三种方法都创建了相同的散列。第一个是.group_by,最简单。

#2


3  

Here are three ways to obtain the desired result by constructing a hash and then extracting the values.

这里有三种方法,可以通过构造散列并提取值来获得所需的结果。

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

# 1

This uses the form of Hash::new that includes a block that is invoked when h[k] is executed, for a hash h that has no key k.

这使用了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

# 2

This is equivalent to #1.

这等价于第一条。

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

#3

# 3

This uses the form of Hash#update (aka merge!) that employs a block (here { |_,o,n| o+n }) to determine the value of keys that are present in both hashes being merged. See the doc for the definitions of the three variables of the value-determining block.

这使用了使用一个块(这里是{|_,o,n| o+n})的散列#更新的形式,以确定在两个散列中出现的键的值。有关价值决定块的三个变量的定义,请参阅doc。

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

#1


6  

Given:

考虑到:

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}
]

You can use .group_by to get a hash of elements by key. In this case, use the key ["beneficiary_document"] passed to the block and you will get a hash of arrays by that key -- two in this case.

您可以使用.group_by来通过键获取元素的散列。在本例中,使用传递给块的键["有权受益者_document"],您将通过该键获得数组的散列——在本例中是2。

You can do:

你能做什么:

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}]}

To see it pretty printed:

看到它印得很漂亮:

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}]}

You can also achieve the same result with a hash that returns an array as a default procedure, then call .map over tst and push the hash into the array by that key:

您还可以使用一个作为默认过程返回数组的散列实现相同的结果,然后通过tst调用.map并通过该键将散列推入数组:

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

Or, combine that into a single statement:

或者,把它合并成一句话:

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

All three methods create identical hashes. The first, .group_by, is the easiest.

这三种方法都创建了相同的散列。第一个是.group_by,最简单。

#2


3  

Here are three ways to obtain the desired result by constructing a hash and then extracting the values.

这里有三种方法,可以通过构造散列并提取值来获得所需的结果。

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

# 1

This uses the form of Hash::new that includes a block that is invoked when h[k] is executed, for a hash h that has no key k.

这使用了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

# 2

This is equivalent to #1.

这等价于第一条。

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

#3

# 3

This uses the form of Hash#update (aka merge!) that employs a block (here { |_,o,n| o+n }) to determine the value of keys that are present in both hashes being merged. See the doc for the definitions of the three variables of the value-determining block.

这使用了使用一个块(这里是{|_,o,n| o+n})的散列#更新的形式,以确定在两个散列中出现的键的值。有关价值决定块的三个变量的定义,请参阅doc。

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