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