繁体   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