簡體   English   中英

如何映射哈希數組並在空日期項目上輸出0?

[英]How do I map an array of hashes and output 0 on empty date items?

我有一系列哈希:

items = [
   {:created=>"2013-12-01", :amount=>16611},
   {:created=>"2013-12-02", :amount=>16611}, 
   {:created=>"2013-12-04", :amount=>9428},
   {:created=>"2013-12-05", :amount=>11628},
   {:created=>"2013-12-06", :amount=>4600},
   {:created=>"2013-12-09", :amount=>21756},
   {:created=>"2013-12-10", :amount=>18127}
]

您會注意到,序列(3、7和8)中缺少許多日期。

我有一張map ,將這些散列輸出到僅包含與日期范圍匹配的散列數量的數組中:

items.select{ |key| (Date.parse("December 1, 2013")..Date.parse("December 12, 2013")).include? Date.parse(key[:created])}.map { |key| key[:amount] }

現在,它將amount項目的全部內容輸出到一個數組中: [16611, 16611, 9428, 11628, 4600, 21756, 18127]

但是我需要做的是為范圍中缺少的日期插入一個0 因此,在我的示例中,我的范圍是12月1日至12月12日。因此,輸出為:

[16611, 16611, 0, 9428, 11628, 4600, 0, 0, 21756, 18127, 0, 0]

我怎樣才能做到這一點?

因為每個人都喜歡單線:

Hash[(Date.parse("December 1, 2013")..Date.parse("December 12, 2013")).map { |x| [x,{:created=>x,:amount=>0}]}+ items.map { |x| [Date.parse(x[:created]),x] }].map { |i| i[1][:amount]}

基本上,使用空值創建我們想要的日期的數組,然后將實值添加到數組的末尾。 轉換為哈希,從而覆蓋它們存在的較早的空值,然后遍歷結果。 在Ruby> = 1.9.2中,您可以按原始順序獲得密鑰。

[16611, 16611, 0, 9428, 11628, 4600, 0, 0, 21756, 18127, 0, 0]
lookup = Hash[*items.flat_map { |it| [Date.parse(it[:created]),it[:amount]] }]

(0..11).map { |i| lookup.fetch(Date.new(2013,12,1)+i,0) }

[16611、16611、0、9428、11628、4600、0、0、21756、18127、0、0]

給定日期范圍:

r = (Date.parse("December 1, 2013")..Date.parse("December 12, 2013"))

並假設items中的日期是唯一的(似乎是這種情況),我可以這樣進行:

b = items.each_with_object({}) {|g,h| h[Date.parse(g[:created])] = g[:amount]}
r.map { |d| b[d] ? b[d] : 0 }
   #=> [16611, 16611, 0, 9428, 11628, 4600, 0, 0, 21756, 18127, 0, 0]

我們首先創建的元素的哈希k=>v ,每個對應於一個元件hitems ,使得k = Date.parse(h[:created])v = h[:amount]

b = items.each_with_object({}) {|g,h| h[Date.parse(g[:created])] = g[:amount]}
  #=> {#<Date: 2013-12-01 ((2456628j,0s,0n),+0s,2299161j)>=>16611,
  #    #<Date: 2013-12-02 ((2456629j,0s,0n),+0s,2299161j)>=>16611,
  #    #<Date: 2013-12-04 ((2456631j,0s,0n),+0s,2299161j)>=> 9428,
  #    #<Date: 2013-12-05 ((2456632j,0s,0n),+0s,2299161j)>=>11628,
  #    #<Date: 2013-12-06 ((2456633j,0s,0n),+0s,2299161j)>=> 4600,
  #    #<Date: 2013-12-09 ((2456636j,0s,0n),+0s,2299161j)>=>21756,
  #    #<Date: 2013-12-10 ((2456637j,0s,0n),+0s,2299161j)>=>18127}

接下來,如果b包含鍵d ,則使用map將范圍r每個成員d轉換為b[d] ,否則d轉換為零。

另外,我們可以這樣做:

items.each_with_object({}) { 
  |g,h| h[Date.parse(g[:created])] = g[:amount] }
    .values_at(*(rng.to_a))
    .map {|v| v.nil? ? 0 : v}

在按上述方式計算完哈希之后,我們使用Hash#values_at創建一個數組,其中包含哈希中的值,以及rng每個日期的nil ,而b沒有匹配項:

c = items.each_with_object({}) {|g,h|
  h[Date.parse(g[:created])] = g[:amount]}.values_at(*rng.to_a)
  #=> [16611, 16611, nil, 9428, 11628, 4600, nil, nil, 21756, 18127, nil, nil]

最后,將nil映射為零:

c.map {|v| v.nil? ? 0 : v}
  #=> [16611, 16611, 0, 9428, 11628, 4600, 0, 0, 21756, 18127, 0, 0]

暫無
暫無

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

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