Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Delete Duplicate CA & US holidays

by dirtdog (Scribe)
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
    Untested:
    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 (Curate) 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 (Sage) 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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2015-07-05 03:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls