I've modified your example array as follows:

```
arr = [
{"May 21"=> [{:applications_one=> 20}, {:applications_two=> 0}]},
{"Jun 21"=> [{:applications_two=> 0}, {:applications_one=> 15}]},
{"Jul 21"=> [{:applications_one=> 6}, {:applications_three=>4}]},
{"Aug 21"=> [{:applications_one=> 1}, {:applications_two=> 2}]},
{"Sep 21"=> [{:applications_one=> 8}, {:applications_two=> 11}]},
{"Oct 21"=> [{:applications_three=>7}, {:applications_one=> 1}]}
]
```

My purpose in doing so is to show that the code I suggest below:

- does not require the hashes within the values (arrays) of the date strings to be ordered;
- does not require the names of the keys of the hashes within the values (e.g.,
`:applications_one`

) to be known in advance; and
- allows the values (arrays) of the date strings to contain any number of hashes.

The values of interest can be computed as follows.

```
arr.each_with_object(Hash.new { |h,k| h[k] = [] }) do |g,h|
date, a = g.flatten
h[:dates] << date
a.each do |f|
label, value = f.flatten
h[label] << value
end
end
#=> {
# :dates=>["May 21", "Jun 21", "Jul 21", "Aug 21", "Sep 21", "Oct 21"],
# :applications_one=>[20, 15, 6, 1, 8, 1],
# :applications_two=>[0, 0, 2, 11],
# :applications_three=>[4, 7]
}
```

The calculations proceed as follows.

Initially,

```
h = Hash.new { |h,k| h[k] = [] }
#=> {}
```

The first hash is then passed to the block (held by the block variable `g`

) and block operations are performed.

```
g = {"May 21"=> [{:applications_one=> 20}, {:applications_two=> 0}]}
```

```
date, a = g.flatten
#=> ["May 21", [{:applications_one=>20}, {:applications_two=>0}]]
# therefore, date #=> "May 21" and
# a #=> [{:applications_one=>20}, {:applications_two=>0}]]
```

See Hash#flatten.

```
h[:dates] << date
# now h #=> {:dates=>["May 21"]}
```

```
a.each do |f|
puts "f=#{f}"
label, value = f.flatten
puts "label=#{label}, value=#{value}"
h[label] << value
puts "h=#{h}\n"
end
```

The following is displayed:

```
f={:applications_one=>20}
label=applications_one, value=20
h={:dates=>["May 21"], :applications_one=>[20]}
f={:applications_two=>0}
label=applications_two, value=0
h={:dates=>["May 21"], :applications_one=>[20], :applications_two=>[0]}
```

The next element of `arr`

is now passed to the block and the block calculations are performed.

```
g #=> {"Jun 21"=> [{:applications_two=> 0}, {:applications_one=> 15}]}
```

```
date, a = g.flatten
#=> ["Jun 21", [{:applications_two=>0}, {:applications_one=>15}]]
# therefore, date #=> "Jun 21" and
# a #=> [{:applications_two=>0}, {:applications_one=>15}]
```

```
h[:dates] << date
# now h #=> {:dates=>["May 21", "Jun 21"]}
```

```
a.each do |f|
puts "f=#{f}"
label, value = f.flatten
puts "label=#{label}, value=#{value}"
h[label] << value
puts "h=#{h}\n"
end
```

The following is displayed.

```
f={:applications_two=>0}
label=applications_two, value=0
h={:dates=>["May21", "Jun21"], :applications_one=>[20],
:applications_two=>[0, 0]}
f={:applications_one=>15}
label=applications_one, value=15
h={:dates=>["May21", "Jun21"], :applications_one=>[20, 15],
:applications_two=>[0, 0]}
```

The remaining calculations are similar.

Note that when the second element of `arr`

was passed to the block,

```
h #=> {:dates=>["May 21"], :applications_one=>[20],
# :applications_two=>[0]} g[:date] #=> "Jun 21"
```

the following calculation makes perfect sense:

```
h[:dates] << date
#=> ["May 21"] << "Jun 21"
#=> ["May 21", "Jun 21"]
```

By contrast, when the first element of `arr`

was passed to the block, the following calculation was performed when `h #=> {}`

, and therefore `h[:dates] #=> nil`

:

```
h[:dates] << date
h #=> {:dates=>["May 21"]}
```

You might wonder why this works, since `nil`

does not have a method `<<`

. It's because of the way `h`

was defined:

```
h = Hash.new { |h,k| h[k] = [] }
```

See the form of Hash::new that takes a block (and therefore no argument).

What this means is that if `h`

does not have a key `k`

and may be altered by operation, the assignment `h[k] = []`

is performed first. (This does not apply to, for example, `m = h[k]; m #=> nil`

, as `h`

is not being altered.)

After having processed

```
{"May 21"=> [{:applications_one=> 20}, {:applications_two=> 0}]}
```

the hash we are building is as follows:

```
h #=> {:dates=>["May 21"], :applications_one=>[20],
# :applications_two=>[0]}
```

For the example given in the question the following is returned:

```
{:dates=>["May 21", "Jun 21", "Jul 21", "Aug 21"],
:applications_one=>[20, 15, 8, 1],
:applications_two=>[0, 0, 11, 2]}
```