Thank you, this worked for me and I also find it simple to understand and to use. Can I ask you just one more question, I'd like to sort my weeks before doing the sum, in this case 1238 will have the "Total_IN1" => 125, how can I do this?
–
salameyNov 22 '12 at 14:27

It would make this a lot easier if you kept your week data as a hash instead of as an array. It was like this in your previous questions, and I wonder if the change to an array is accidental or deliberate? Sorting the data as it stands is possible but not straightforward, and I have added a block to my solution to show how to do it. But please revert to a hash if you possible can.
–
BorodinNov 22 '12 at 14:45

Thank you, but what if I had other Weeks? 1226 1238 1227 1239 with your method it'll return 1239 1227 1238 1226 and it's not what I need, I need to sort them numerically.
–
salameyNov 22 '12 at 14:56

The change I have made to the code sorts the data by week number, as the output shows. I'm just saying it would be a lot more straightforward if you hadn't changed to using an array.
–
BorodinNov 22 '12 at 15:02

Sorry - there was a bug in my code. Fixed.
–
BorodinNov 22 '12 at 15:03

First, your data structure is confusing. 'Week' is a reference to an array, some of whose elements are strings (such as '1238') and the rest of whose elements are hash references.

While Perl lets you get away with this, it would be a better design for each level of your data structure to hold only one kind of thing. This is something to consider. However, I will leave it as is for now.

grep {ref $_} gets only the elements that are hash references out of the array.

$_->{'IN1'} || 0 - If one of the hashes did not have 'IN1', this would use zero instead. This is basically a check for the hash key being defined. || is acceptable to do this for hash keys. In other situations, however, you need the defined-or operator (//, available from version 5.10 I believe).

$_->{'In1Total'} = $total+=$_->{'IN1'} || 0 this adds the current value of IN1 to the count, then puts the result into In1Total. Admittedly this could be made a bit clearer by separating it into a couple of lines.

Nice, concise, functional, I like it. Can be difficult to read for less experienced, however. Also, if stuck on an ancient version of perl, I think you could use || in place of // in this case.
–
Mikko LNov 22 '12 at 12:45

@MikkoL, thanks for your helpful comments. I have made the change you suggested, as well as added some explanation. I wanted to show that the code could be made a lot simpler, but perhaps I was overzealous in reducing it down.
–
dan1111Nov 22 '12 at 13:18

The functional approach is excellent in many ways and definitely worth learning, not to mention elegant (IMHO). Your code with the added explanation is a great resource to get started! Thank you for contributing!
–
Mikko LNov 22 '12 at 13:27

This code won't run under use strict and use warnings, so I suggest using grep ref, @{$VAR1->{Week}} instead. Also there is little point in using || over // when what you really mean is exists $_->{IN1} ? $_->{'IN1'} : 0. I believe // is preferable.
–
BorodinNov 22 '12 at 14:15

@Borodin, thanks for pointing that out. Whoops! Commenting out use strict; while testing something then forgetting to put it back in = a bad idea. As for // vs. ||, they work the same in this case and neither one produces a warning on a key that doesn't exist.
–
dan1111Nov 22 '12 at 14:33

Come on, why the downvote? I didn't use bad practices, I helped the OP to improve his solution instead of rewriting it completely and I tested my code with the right result. At least leave a comment.
–
memoweNov 22 '12 at 18:19