[英]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
,每个对应于一个元件h
的items
,使得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.