Ruby 从数组中匹配元素

Ruby 从数组中匹配元素,ruby,set,matching,Ruby,Set,Matching,我的数据结构如下所示 [{"league"=>:nba, "period"=>"h1","edge"=>-5.0, "home_team"=>"Cavaliers"}, {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Pistons"}, {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_tea

我的数据结构如下所示

[{"league"=>:nba, "period"=>"h1","edge"=>-5.0, "home_team"=>"Cavaliers"},   
{"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Pistons"}, 
{"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Bucks"},   
{"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin"},   
{"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin"}]
我需要为数组中的每个元素分配一个新的键/值对,key=id,value=x,其中x是一个整数。对于周期和主团队值相同的每个元素,x应该相同,否则x是什么并不重要。因此,上述结果应该是这样的:

[{"league"=>:nba, "period"=>"h1","edge"=>-5.0, "home_team"=>"Cavaliers", "id"=>1},   
{"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Pistons", "id"=>2},    
{"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Bucks", "id"=>3},  
{"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin", "id"=>4},   
{"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin", "id"=>4}]
使用计数哈希:

pair_ids = Hash.new { |_, pair| pair_ids[pair] = pair_ids.length }

items = [ 
  {"league"=>:nba, "period"=>"h1","edge"=>-5.0, "home_team"=>"Cavaliers"}   ,
  {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Pistons"}    ,
  {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Bucks"}   ,
  {"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin"}   ,
  {"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin"}
]

items.each do |item|
   item["id"] = pair_ids[ item.values_at("home_team", "period") ]
end

# now, items == [
#   {"league"=>:nba, "period"=>"h1", "edge"=>-5.0, "home_team"=>"Cavaliers", "id"=>0}, 
#   {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Pistons", "id"=>1}, 
#   {"league"=>:nba, "period"=>"h1", "edge"=>-6.0, "home_team"=>"Bucks", "id"=>2}, 
#   {"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin", "id"=>3}, 
#   {"league"=>:ncaab, "period"=>"h1", "edge"=>-7.0, "home_team"=>"Wisconsin", "id"=>3}
# ]
new接受为每个与现有密钥不匹配的查找运行的块。我们用这个 块以缓存每个主团队/时段对的新id。

您可以使用:

代码

例子

解释

对于上面的第二个示例数组项:

在计算b时,传递给块的第一个数组被分配给以下给定的块变量

|(k,v),i|
详情如下:

k = ["h1", "Cavaliers"]
v = [{"league"=>:nba1, "period"=>"h1", "home_team"=>"Cavaliers"},
     {"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers"}], 
i = 0
我们将不使用k,因此将其作为块变量替换为u

映射将v的第一个元素转换为:

第二个要素是:

{"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers"}.merge({id: 0})
  #=> {"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers", :id=>0}

只需使用散列码!我对这个问题提交了两个答案。这是一个事后的想法,但我更喜欢它,而不是我的另一个解决方案。它利用了这种方法

代码

范例


您的数据结构无效。现在我的数据结构是validIt,在Hash.new块中引用外部变量对_id,而不是它给您分配给u的哈希的引用,这有点奇怪。我想新手更容易理解这很酷。也许我可以解释一下。rampion在构建散列对\u id的同时,向项的每个元素添加一个键值对。对于项目的第一项,让k=item.values\u athome\u团队,句点=>[Cavaliers,h1]。pair_id没有此密钥k,因为它是空的,所以pairs_idk被分配给pairs_id.size,它等于0,然后被分配给item[id]。pairs_id现在是{[Cavaliers,h1]=>0}…待定…我们现在进入项目的第二个元素。pairs\u id没有a键[h1,活塞],因此[h1,活塞]=>1,因为pairs\u id.size=>1被添加到pairs\u id和item[id]=>1。类似地,将项[id]=>2添加到第三个散列,并将项[id]=>3添加到第四个散列。对于items的最后一个元素,我们在pairs_id中搜索键[Wisconsin,h1]。当pairs_id=>{[Cavaliers,h1]=>0,[Piones,h1]=>1,[Bucks,h1]=>2,[Wisconsin,h1]=>3}时,密钥被找到了,所以项[id]`被分配给pairs_id[[Wisconsin,h1]],等于3。啊,我终于找到了散列中的块。新的{x,y}有x表示散列本身,y表示你传递的密钥,我假设x,y是密钥,值对。现在我明白了。参考,优雅的功能解决方案!
|(k,v),i|
k = ["h1", "Cavaliers"]
v = [{"league"=>:nba1, "period"=>"h1", "home_team"=>"Cavaliers"},
     {"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers"}], 
i = 0
{"league"=>:nba1, "period"=>"h1", "home_team"=>"Cavaliers"}.merge({id: 0})
  #=> {"league"=>:nba1, "period"=>"h1", "home_team"=>"Cavaliers", :id=>0}
{"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers"}.merge({id: 0})
  #=> {"league"=>:nba4, "period"=>"h1", "home_team"=>"Cavaliers", :id=>0}
items.each{|h|h["id"]={"period"=>h["period"],"home_team"=>h["home_team"]}.hash}  
items = [{"league"=>:nba, "per"=>"h1", "ht"=>"Cavaliers"},
         {"league"=>:nba, "per"=>"h1", "ht"=>"Pistons"},
         {"league"=>:nba, "per"=>"h1", "ht"=>"Bucks"},
         {"league"=>:ncb, "per"=>"h1", "ht"=>"Wisconsin"},
         {"league"=>:ncb, "per"=>"h1", "ht"=>"Wisconsin"}]

items.each { |h| h["id"] = { "per" => h["per"], "ht" => h["ht"] }.hash }
#=>[{"league"=>:nba,"per"=>"h1","ht"=>"Cavaliers","id"=>-4168551181113196037},
#   {"league"=>:nba,"per"=>"h1","ht"=>"Pistons"  ,"id"=>-1923231267716315157},
#   {"league"=>:nba,"per"=>"h1","ht"=>"Bucks"    ,"id"=>-1538708673911299676},
#   {"league"=>:ncb,"per"=>"h1","ht"=>"Wisconsin","id"=> 377899609258784958},
#   {"league"=>:ncb,"per"=>"h1","ht"=>"Wisconsin","id"=> 377899609258784958}]