简体   繁体   English

将Ruby哈希转换为哈希排序数组

[英]Conversion of Ruby Hashes to Sort array of Hash

I have following input: 我有以下输入:

array = [{:year=>2015, :platform_id=>2},
        {:year=>nil,  :platform_id=>2},
        {:year=>nil,  :platform_id=>4},
        {:year=>2015, :platform_id=>4}]

I need expected result to be: 我需要预期的结果是:

[{platform_id=>2, year=>[2015, nil]},
 {platform_id=>4, year=>[nil, 2015]}]

What I code is: 我写的是:

array.inject(:merge)

But that gets me this result, which is not what I want: 但这让我得到了这个结果,这不是我想要的:

{:year=>2015, :platform_id=>4}

Updated below after answer received: 收到答案后,在下面进行了更新:

I do performance test after see the answers and here is the result: 看到答案后,我进行了性能测试,结果如下:

arr = [
  {:year => 2015, :platform_id => 2},
  {:year => nil, :platform_id => 2},
  {:year => nil, :platform_id => 4},
  {:year => 2015, :platform_id => 4}
]

#approach 1
x1 = Time.now.to_f
exp = arr.each_with_object({}) do |h, exp|
  exp[h[:platform_id]] ||= {:platform_id => h[:platform_id], :year => []}
  exp[h[:platform_id]][:year] << h[:year]
end.values
x2 = Time.now.to_f
p x2-x1

#approach 2
x3 = Time.now.to_f
new_data = arr.group_by { |d| d[:platform_id] }
new_arr = []
new_data.each do |k,v|
 t2 = v.map{|x| x[:year]}
 temp = {"platform_id": k, "years": t2}
 new_arr.push(temp)
end
x4 = Time.now.to_f
p x4-x3 

#approach 3
x5 = Time.now.to_f
f = arr.each_with_object({}) { |g,h|
  h.update(g[:platform_id]=>[g[:year]]) { |_,o,n| o+n } }
  #=> {2=>[2015, nil], 4=>[nil, 2015]} 

f.map { |k,v| { :platform_id=>k, :year=>v } }
x6 = Time.now.to_f
p x6-x5 

#output is:
9.059906005859375e-06
6.4373016357421875e-06
9.775161743164062e-06

You can use each_with_object with hash and print values like this 您可以将each_with_object与哈希和打印值一起使用,如下所示

arr = [
  {:year => 2015, :platform_id => 2},
  {:year => nil, :platform_id => 2},
  {:year => nil, :platform_id => 4},
  {:year => 2015, :platform_id => 4}
]

exp = arr.each_with_object({}) do |h, exp|
  exp[h[:platform_id]] ||= {:platform_id => h[:platform_id], :year => []}
  exp[h[:platform_id]][:year] << h[:year]
end.values

p exp
# => [{:platform_id=>2, :year=>[2015, nil]}, {:platform_id=>4, :year=>[nil, 2015]}]
arr = [
  { :year=>2015, :platform_id=>2 }, 
  { :year=>nil,  :platform_id=>2 },
  { :year=>nil,  :platform_id=>4 },
  { :year=>2015, :platform_id=>4 }
]

arr.each_with_object({}) { |g,h|
  h.update(g[:platform_id]=>[g[:year]]) { |_,o,n| o+n } }.
    map { |k,v| { :platform_id=>k, :year=>v } }
    #=> [{:platform_id=>2, :year=>[2015, nil]},
    #    {:platform_id=>4, :year=>[nil, 2015]}] 

The two steps are as follows. 这两个步骤如下。

f = arr.each_with_object({}) { |g,h|
  h.update(g[:platform_id]=>[g[:year]]) { |_,o,n| o+n } }
  #=> {2=>[2015, nil], 4=>[nil, 2015]} 

f.map { |k,v| { :platform_id=>k, :year=>v } }
  #=> [{:platform_id=>2, :year=>[2015, nil]},
  #    {:platform_id=>4, :year=>[nil, 2015]}] 

The first step uses the form of Hash#update (aka merge! ) that employs a block (here { |_,o,n| o+n } ) that computes the value of keys that are present in both hashes being merged. 第一步使用Hash#update的形式(又名merge! ),该形式采用一个块(此处为{ |_,o,n| o+n } ),该块计算合并的两个哈希中存在的键的值。

Here is the answer: 答案是:

 data = [
 {:year=>2015, :platform_id=>2}, 
 {:year=>nil, :platform_id=>2},
 {:year=>nil, :platform_id=>4},
 {:year=>2015, :platform_id=>4}
]

new_data = data.group_by { |d| d[:platform_id] }


#p new_data

new_arr = []

new_data.each do |k,v|
 t2 = v.map{|x| x[:year]}
 temp = {"pf_id": k, "years": t2}
 new_arr.push(temp)
end

p new_arr 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM