簡體   English   中英

動態嵌套Ruby循環

[英]Dynamic Nested Ruby Loops

因此,我想做的是調用Reporting API,以按所有可能的細目分類(按網站,廣告客戶,廣告類型,廣告系列等細分報告)。 但是,一個問題是細目分類對於每個登錄而言都是唯一的。

例:

  • user1: alice123的報告細分為["site","advertiser","ad_type","campaign","line_items"]
  • user2: bob789的報告細分為["campaign","position","line_items"]

當我第一次為該報告API構建代碼時,我只有一個登錄名可以進行測試,因此我對各個維度( ["site","advertiser","ad_type","campaign","line_items"] )。 所以我所做的就是對API進行ping操作,以獲取sites的報告。 然后,對於每個site (為advertisers ping)和每個advertiser ,我為下一個維度ping等等,以此類推,剩下約6層的嵌套循環。

基本上我在做什么:

sites = mechanize.get "#{base_ur}/report?dim=sites"
sites = Yajl::Parser.parse(sites.body) # json parser

sites.each do |site|
  advertisers = mechanize.get "#{base_ur}/report?site=#{site.fetch("id")}&dim=advertiser"
  advertisers = Yajl::Parser.parse(advertisers.body) # json parser

  advertisers.each do |advertiser|
    ad_types = mechanize.get "#{base_ur}/report?site=#{site.fetch("id")}&advertiser=#{advertiser.fetch("id")}&dim=ad_type"
    ad_types = Yajl::Parser.parse(ad_types.body) # json parser

    ad_types.each do |ad_type|
      ...and so on...
    end
  end
end

GET <api_url>/?dim=<dimension to breakdown>&site=<filter by site id>&advertiser=<filter by advertiser id>...etc...

在嵌套循環的末尾,我得到了一份盡可能細化的報告。

現在這行得通,因為我只認為存在分解的路徑,但是顯然每個帳戶可能會有不同的維度細分。

因此,我要問的是,如果給定一組故障,如何設置嵌套循環以動態向下遍歷粒度奇點?

謝謝。

我不確定您的JSON / GET到底返回什么,但是對於這樣的問題,您需要遞歸。

大概是這樣嗎? 它不是很優雅,可以肯定地進一步優化,但是希望可以給您一個想法。

some_hash = {:id=>"site-id", :body=>{:id=>"advertiser-id", :body=>{:id=>"ad_type-id", :body=>{:id=>"something-id"}}}}
@breakdowns = ["site", "advertiser", "ad_type", "something"]

def recursive(some_hash, str = nil, i = 0)
  if @breakdowns[i+1].nil?
    str += "#{@breakdowns[i]}=#{some_hash[:id]}"
  else
    str += "#{@breakdowns[i]}=#{some_hash[:id]}&dim=#{@breakdowns[i + 1]}"
  end

  p str

  some_hash[:body].is_a?(Hash) ? recursive(some_hash[:body], str.gsub(/dim.*/, ''), i + 1) : return
end

recursive(some_hash, 'base-url/report?')

=> "base-url/report?site=site-id&dim=advertiser"
=> "base-url/report?site=site-id&advertiser=advertiser-id&dim=ad_type"
=> "base-url/report?site=site-id&advertiser=advertiser-id&ad_type=ad_type-id&dim=something"
=> "base-url/report?site=site-id&advertiser=advertiser-id&ad_type=ad_type-id&something=something-id"

如果您只是想映射數據,則可以遞歸地映射到另一個用戶指出的哈希。 如果您實際上是想在循環中使用此數據並想要動態地重新創建問題中列出的循環結構(盡管我建議您提供其他解決方案),則可以使用元編程,如下所示:

require 'active_support/inflector'

# Assume we are given an input of breakdowns
# I put 'testarr' in place of the operations you perform on each local variable
# for brevity and so you can see that the code works.
# You will have to modify to suit your needs

result = []
testarr = [1,2,3]
b = binding
breakdowns.each do |breakdown|
  snippet = <<-END
    eval("#{breakdown.pluralize} = testarr", b)
    eval("#{breakdown.pluralize}", b).each do |#{breakdown}|    
  END

  result << snippet 
end

result << "end\n"*breakdowns.length


eval(result.join)

注意:此方法可能不被接受,正如我已經說過的,我確定還有其他方法可以完成您要嘗試執行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM