通过一些键合并哈希数组,并合并其他键的值

时间:2018-07-14 07:05:31

标签: ruby

我有一个像这样的数组

array = [
  {"point"=>6, "score"=>4, "team"=>"Challenger"},
  {"point"=>4, "score"=>2, "team"=>"INB"},
  {"point"=>2, "score"=>2, "team"=>"Super-11"},
  {"point"=>3, "score"=>7, "team"=>"INB"}
]

我想通过“团队”合并哈希并求和“点”和“得分”的值。另外,如果点大于5,则希望在每个哈希中插入一个“限定”键。因此最终结果将是:

result= [
      {"point"=>6, "score"=>4, "qualified"=> "yes", "team"=>"Challenger"},
      {"point"=>7, "score"=>9, "qualified"=> "yes", "team"=>"INB"},
      {"point"=>2, "score"=>2, "qualified"=> "no", "team"=>"Super-11"}
    ]

任何帮助将不胜感激。谢谢!

6 个答案:

答案 0 :(得分:3)

另一个可能的解决方案:)

array.group_by { |item| item['team'] }.map do |_, items| 
  result = items.inject({}) { |hash, item| hash.merge(item) { |_, old, new| Integer(old) + new rescue old } }
  result.merge("qualified" => result['point'] > 5 ? "yes" : "no")
end

答案 1 :(得分:2)

sendRemoteNotification(token,userId,friendId) { let body; if (Platform.OS === "android") { body = { to: token, data: { custom_notification: { title: "New Message available", body: "Don't keep them waiting. Tap to reply.", userId:friendId, friendId:userId, sound: "default", priority: "high", show_in_foreground: false, targetScreen: "chat", } }, priority: 10 }; } else { body = { to: token, notification: { title: "Simple FCM Client", body: "Click me to go to detail", sound: "default" }, data: { targetScreen: "detail" }, priority: 10 }; } }

答案 2 :(得分:2)

结合使用group_bymap

result = 
    array.group_by {|item| item['team'] }
         .map do |team, items|
             total_points = items.map{|item| item['point']}.reduce(0, :+)
             total_score = items.map{|item| item['score']}.reduce(0, :+)
             qualified = points > 5
             {
                 'point' => total_points, 
                 'score' => total_score, 
                 'qualified' => qualified ,
                 'team' => team
             }
          end

答案 3 :(得分:1)

这是替代版本。我想group_by是强制性的。 我使用带有键作为符号的临时哈希在迭代过程中存储数据。

result = array.group_by { |hash| hash['team'] }.map do |team|
  tmp_hash = {point: 0, score: 0, team: team[0], qualified: 'no'}
  team[1].each { |h| tmp_hash[:point] += h['point'] ; tmp_hash[:score] += h['score'] }
  tmp_hash[:qualified] = 'yes' if tmp_hash[:point] > 5
  tmp_hash
end

结果如下:

# => [
#      {:point=>6, :score=>4, :team=>"Challenger", :qualified=>"yes"},
#      {:point=>7, :score=>9, :team=>"INB", :qualified=>"yes"},
#      {:point=>2, :score=>2, :team=>"Super-11", :qualified=>"no"}
#    ]

答案 4 :(得分:0)

完成group_by之后,执行一个简单的map操作,该操作将第一个元素作为映射值,将其中的pointscore求和,然后合并{{ 1}}条件很简单:

qualified

在线演示here

答案 5 :(得分:0)

array.each_with_object({}) do |g,h|
  h.update(g["team"]=>g.merge("qualified"=>g["score"] > 5 ? "yes" : "no")) do |_,o,n|
    { "point"    =>o["point"]+n["point"],
      "score"    =>o["score"]+n["score"],
      "team"     =>o["team"],
      "qualified"=>(o["score"]+n["score"]) > 5 ? "yes" : "no" }
  end
end.values
  #=> [{"point"=>6, "score"=>4, "team"=>"Challenger", "qualified"=>"no"},
  #    {"point"=>7, "score"=>9, "team"=>"INB", "qualified"=>"yes"},
  #    {"point"=>2, "score"=>2, "team"=>"Super-11", "qualified"=>"no"}]

这使用Hash#update(也称为merge!)的形式,该形式采用一个块来确定合并的两个哈希中都存在的键的值(此处为:id的值) 。有关三个块变量(此处为_on的描述,请参见文档。

请注意,values(最后)的接收者是

{"Challenger"=>{"point"=>6, "score"=>4, "team"=>"Challenger", "qualified"=>"no"},
 "INB"=>{"point"=>7, "score"=>9, "team"=>"INB", "qualified"=>"yes"},
 "Super-11"=>{"point"=>2, "score"=>2, "team"=>"Super-11", "qualified"=>"no"}}

或者可以在末尾另外进行一次传递,以添加密钥"qualified'

array.each_with_object({}) do |g,h|
  h.update(g["team"]=>g) do |_,o,n|
    { "point"    =>o["point"]+n["point"],
      "score"    =>o["score"]+n["score"],
      "team"     =>o["team"] }
  end
end.values.
    map { |h| h.merge("qualified"=>(h["score"] > 5) ? "yes" : "no") }
相关问题