in reply to Hash of Arrays? OR Array of Hashes
Just another dimension of thinking -- absolutely not to detract in any way from the excellent posts thus far -- your line:
@chaseList = @$row;You claim you don't fully understand referencing, but it seems like de-referencing is the actual issue. This line is succinct; $row is a scalar which holds a reference to an array. By preceding this with an array indicator (@$row), you have successfully dereferenced it. You then assign this to your array variable @chaseList, making it easier to deal with later in your code.
As an aside, this relationship can also be expressed as @{$row}, which, while largely superfluous, runs the risk of helping the newbie Perl programmer who comes after you to understand your code more intuitively. I personally find this technique very useful because when I deal with deeper structures, a light version of which might be arrays of hashes of arrays, using the extra braces helps me keep track of what is being referenced without having to dereference it as a separate step. But I digress.)
Completely off the original question, a thought about this line:
my $month = substr ($chaseList[1], 0, );I would be more inclined to use split here, breaking the date into an array from three fields separated by a slash. Not only is this likely to be more forgiving of issues like a change in the format of the data source to suddenly not including leading zeroes on the month, but it makes it easier to code defensively for a change in format, say, from U.S. to European, or slashes vs. dashes, without a lot of hassle (though handling date formats is a headier topic and I'm not here to fight those religious battles today LOL)
my @dateParts = split /[\/\-]/, $chaseList[1]; my $month = $dateParts[0]; # For purposes of example; see note belo +w
This starts to open the possibility of handling a variety of date format changes from the source of your CSV file, though to make this truly flexible you'd have to add some bulk to the code, and I would envision a subroutine called getMonth() in order to more flexibly extract the proper month field...but even as written it handles dashes or slashes and presence or absence of a leading zero on the month field.
And then we have the crux of your question:
my $temp = $chaseList[3] + %@chaseArray[$month]{Shopify};So you have @ChaseArray, and you want the element of that array referencing the month.
$chaseArray[$month]Now, without commenting on the rest of the code for the moment, this line suggests you want that to be an array of hashes, referencing that hash by the vendor.
For readability's sake, I'd accept the performance hit of an extra line of code or two:
$vendor = $chaseList[2]; $amount = $chaseList[3]; # Now we can directly reference the hash by vendor inside the arra +y by month number: # $chaseArray[$month]{$vendor}
You could also make the conversion from raw array to data in one line, very Perl... and -- making some potentially terrible assumptions about the third field in the CSV -- further snag the vendor as the first word of the transaction description, if that pattern holds:
my ( $tranType, $tranDate, $tranDesc, $tranAmount, $tranMedium, @extraStuffJustInCase ) = split /\,/, @chaseList; my ($tranVendor, @restOfDesc) = split /\s/, $tranDesc;
Now that you've done that, it's a cinch to get back to what your commented-out code suggests may have been your original intent:
$chaseArray[$month]{$tranVendor} += $tranAmount;
Based on the well-crafted snippet you provided (Thank you!), and if the assumption about the vendor being identifiable strictly by the first word in what I have called the Description field, it looks like this might help you eliminate a long and source-code-maintained list of vendors by if ... elseif ... elseif (or case statement) -- and, frankly, that code simplification would be the real benefit of using a hash.
|
|---|