Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Delete Duplicate CA & US holidays

by dirtdog (Beadle)
on Mar 01, 2012 at 20:49 UTC ( #957314=perlquestion: print w/ replies, xml ) Need Help??
dirtdog has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I'm stumped on an issue that shouldn't be very complex, but I'm having a difficult time coming up with a solution

I build an array of hashes that reads thru a global holiday calendar and populates it with only US & CA holiday dates. Once i have the array of hashes populated I want to remove any holiday dates they both share. For example, they both share 20121225 as xmas holiday. In this case i would like it removed from the array of hashes.

#!/usr/bin/env perl use warnings; use strict; my %countries; my %seen; my @dup; my @countries; my $holiday; my @cntry_of_issue = ('US','CA'); while (<DATA>) { chomp; next if /^\s*$/ || /^\#/; my $aref = [split /,/, $_]; push( @{$countries{$aref->[2]}}, $aref->[5]); } sub strip_US_CA_dup_hols { for (@cntry_of_issue) { foreach $holiday (@{$countries{$_}}) { $seen{$holiday}++; } }#end of for while ( my ($key, $value) = each %seen ) { push @dup,$key if $value > 1; } for (@cntry_of_issue) { delete $@{$countries{$_}} if grep /@{$countries{$_}}/, @dup; } }#end of function &strip_US_CA_dup_hols; __DATA__ 808,XNYS,US,New York Stock Exchange,2012,20120102,Mon,New Year's Day O +BS,T 808,XNYS,US,New York Stock Exchange,2012,20120116,Mon,Martin Luther Ki +ng Jr. Day,T 808,XNYS,US,New York Stock Exchange,2012,20120220,Mon,Presidents' Day, +T 808,XNYS,US,New York Stock Exchange,2012,20120406,Fri,Good Friday,T 808,XNYS,US,New York Stock Exchange,2012,20120528,Mon,Memorial Day,T 808,XNYS,US,New York Stock Exchange,2012,20120704,Wed,Independence Day +,T 808,XNYS,US,New York Stock Exchange,2012,20120903,Mon,Labor Day,T 808,XNYS,US,New York Stock Exchange,2012,20121122,Thu,Thanksgiving,T 808,XNYS,US,New York Stock Exchange,2012,20121225,Tue,Christmas,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120102,Mon,New Year's Day OB +S,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120220,Mon,Family Day,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120406,Fri,Good Friday,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120521,Mon,Victoria/Patriots +' Day,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120702,Mon,Canada Day OBS,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120806,Mon,Civic Holiday,T 665,XTSE,CA,Toronto Stock Exchange,2012,20120903,Mon,Labour Day,T 665,XTSE,CA,Toronto Stock Exchange,2012,20121008,Mon,Thanksgiving,T 665,XTSE,CA,Toronto Stock Exchange,2012,20121225,Tue,Christmas,T 665,XTSE,CA,Toronto Stock Exchange,2012,20121226,Wed,Boxing Day,T

I sent and earlier post that was not correct by mistake. This one is actually legible. Any help would be greatly appreciated. Thanks

Comment on Delete Duplicate CA & US holidays
Download Code
Re: Delete Duplicate CA & US holidays
by Corion (Pope) on Mar 01, 2012 at 21:05 UTC

    My advice on calendars, especially stock exchange calendars, is to keep them separate. Stuff them in a database table, even if it's just DBD::SQLite. You'll be surprised how useful it gets to have calendars in a database.

    If you want the consolidated holidays, you can use the following SQL query:

    select holiday_date, count(*) as occurs from calendar where exchange in ('XNYS','XTSE') group by holiday_date having occurs = 2
Re: Delete Duplicate CA & US holidays
by JavaFan (Canon) on Mar 01, 2012 at 21:07 UTC
    my %holiday; while (<DATA>) { my (undef, undef, $cc, undef, undef, $date) = split /,/; $holiday{$cc}{$date} = 1; } delete $holiday{US}{$_} for keys %{$holiday{CA}}; delete $holiday{CA}{$_} for keys %{$holiday{US}}; # Turn into a hash of array: $holiday{$_} = [sort keys %{$holiday{$_}}] for qw[US CA];
Re: Delete holiday from array of hashes when US & CA share a holiday
by tangent (Deacon) on Mar 01, 2012 at 21:21 UTC
    Update: this comment was moved from another node where the OP was garbled.

    A bit hard to decipher because although you did use code tags you didn't use them properly. Quite a few improvements could be made but a quick solution would be to change your function like so:

    sub strip_US_CA_dup_hols { for my $country (@cntry_of_issue) { for my $holiday (@{$countries{$country}}) { $seen{$holiday}++; } } for my $country (@cntry_of_issue) { my $aref = $countries{$country}; @$aref = grep { $seen{$_} < 2 } @$aref; } } # Prints: 'US' => [ '20120116', '20120528', '20120704', '20121122' ], 'CA' => [ '20120521', '20120702', '20120806', '20121008', '20121226' ]
Re: Delete Duplicate CA & US holidays
by GrandFather (Cardinal) on Mar 01, 2012 at 22:22 UTC

    One way you could do it is while you parse the input file keep a count of how many times each date is encountered then filter the holiday info based on that. Consider:

    #!/usr/bin/env perl use warnings; use strict; my %holidays; my %common; while (<DATA>) { chomp; next if /^\s*$/ || /^\#/; my $aref = [split /,/, $_]; push @{$holidays{$aref->[2]}}, $aref->[5]; ++$common{$aref->[5]}; } my $countries = keys %holidays; for my $country (keys %holidays) { @{$holidays{$country}} = grep {$common{$_} != $countries} @{$holid +ays{$country}}; }
    True laziness is hard work

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://957314]
Approved by davies
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2014-08-23 10:20 GMT
Find Nodes?
    Voting Booth?

    The best computer themed movie is:

    Results (173 votes), past polls