[英]Get unique element on basis of string from array of hash
I have an array of hashes: 我有一系列哈希:
[{:a => "63-aaa",:b =>1}, {:a => "90-bbb",:b => 89}, {:a => "63-aaa", :b => 1},{:a => "45-hhh", :b => 44}, {:a => "32-kkk", :b => 67}, {: => "90-bbb", :b => 89}]
a
key has value 63-aaa
, 90-bbb
, 45-hhh
and 32-kkk
. a
钥匙的价值是63-aaa
, 90-bbb
, 45-hhh
和32-kkk
。 I want to get the unique elements of the array on the basis of ids of values of a
like: 我想要得到的值的ID的基础上,数组的独特元素
a
样:
[{:a => "63-aaa",:b =>1}, {:a => "90-bbb",:b => 89}, {:a => "45-hhh", :b => 44}, {:a => "32-kkk", :b => 67}]
在这种情况下,您可以将块传递给Array#uniq
:
arr.uniq { |hash| hash[:a] }
You don't appear to care which one of each set of duplicates is kept. 您似乎并不关心保留每组重复项中的哪一项。
Array#uniq
, with a block, is purpose-built for that. 带有块的
Array#uniq
是专门为此而构建的。 It will keep the one with the smallest index. 它将保持索引最小的那个。 If you want the one with the largest index, just apply
Array#reverse
before and after uniq
. 如果你想要索引最大的那个,只需在
uniq
之前和之后应用Array#reverse
。
If, however, you wanted to use other information in each hash to determine which one to keep, you could do that by using the form of Hash#update (aka merge!
) that takes a block: 但是,如果您想在每个哈希中使用其他信息来确定要保留哪个信息,则可以使用Hash#update (aka
merge!
)的形式来执行此操作:
arr = [{:a=>"63-aaa", :b=> 1}, {:a=>"90-bbb", :b=>89}, {:a=>"63-aaa", :b=>22},
{:a=>"45-hhh", :b=>44}, {:a=>"32-kkk", :b=>67}, {:a=>"90-bbb", :b=>14}]
arr.each_with_object({}) do |g,h|
h.update({ g[:a]=>g }) { |k,oh,nh| <code to return oh or nh> }
end.values
Suppose, for example, you want to keep the hash h
for which h[:b]
is largest: 例如,假设您要保留
h[:b]
最大的哈希值h
:
arr.each_with_object({}) do |g,h|
h.update({ g[:a]=>g }) { |k,oh,nh| nh[:b] > oh[:b] ? nh : oh }
end.values
#=> [{:a=>"63-aaa", :b=>22}, {:a=>"90-bbb", :b=>89},
# {:a=>"45-hhh", :b=>44}, {:a=>"32-kkk", :b=>67}]
I have created an empty hash (block variable h
), and then for each hash g
in arr
, update h
with the hash f = { g[:a]=>g }
. 我创建了一个空哈希(块变量
h
),然后对于arr
每个哈希g
,使用哈希值f = { g[:a]=>g }
更新h
。 If both h
and f
have the key g[:a]
, the block 如果
h
和f
都有密钥g[:a]
,则为块
{ |k,oh,nh| (nh[:b] > oh[:b]) ? nh : oh }
is called upon to determine the value of the key g[:a]
in h
(that is, which of the two hashes to keep). 被要求确定
h
中的键g[:a]
的值(即,要保留的两个哈希值中的哪一个)。 The block variables are: 块变量是:
k = g[:a]
oh = h[g[:a]]
nh = g
(Note that k
is not used in the block, so we might write the block variables as |_,oh,nh|
.) (注意块中没有使用
k
,所以我们可以将块变量写成|_,oh,nh|
。)
each_with_object
returns each_with_object
返回
h = {"63-aaa"=>{:a=>"63-aaa", :b=>22}, "90-bbb"=>{:a=>"90-bbb", :b=>89},
"45-hhh"=>{:a=>"45-hhh", :b=>44}, "32-kkk"=>{:a=>"32-kkk", :b=>67}}
so we merely have to extract the values: 所以我们只需要提取值:
h.values
#=> [{:a=>"63-aaa", :b=>22}, {:a=>"90-bbb", :b=>89},
# {:a=>"45-hhh", :b=>44}, {:a=>"32-kkk", :b=>67}]
Another way is to first execute: 另一种方法是先执行:
arr.group_by { |h| h[:a] }.values
#=> [[{:a=>"63-aaa", :b=> 1}, {:a=>"63-aaa", :b=>22}],
# [{:a=>"90-bbb", :b=>89}, {:a=>"90-bbb", :b=>14}],
# [{:a=>"45-hhh", :b=>44}],
# [{:a=>"32-kkk", :b=>67}]]
and then use whatever criteria you like to select one hash from each of the four arrays. 然后使用您喜欢的任何条件从四个阵列中的每一个中选择一个哈希。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.