Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Searching in an array of arrays

by zejames (Hermit)
on Nov 03, 2004 at 12:09 UTC ( #404872=note: print w/replies, xml ) Need Help??


in reply to Searching in an array of arrays

One way to do it (untested) :
my $consecutive = 5; my ($last_range, $first_day); my %ranges = ( '15' => 'mild', '20' => 'warm', '25' => 'verywarm', '30' => 'hot', '35' => 'veryhot', '40' => 'extremelyhot'); foreach my $day (@data) { $day->[1] = int $day->[1]; my $range = $day->[1] - ($day->[1] % 5); if ($range == $last_range) { $seen++; } else { $last_range = $range; $first_day = $day->[0]; $seen = 1; } if ($seen == $consecutive) { print "$first_day $day->[0] " . $ranges{$range} . "\n"; } }
BTW, a hash table would probably be more appropriate to store your tempature information.

updated : corrected $last_range and $first_day, and make it word in Real world


--
zejames

Replies are listed 'Best First'.
Re^2: Searching in an array of arrays
by Taulmarill (Deacon) on Nov 03, 2004 at 13:53 UTC
    hm, at first sight i would say that $last_range, $first_day should be initialised outside the for-loop. look at and execute this:
    for ( 1 .. 10 ) { my $i; $i++; print $i; } print "\n"; my $i; for ( 1 .. 10 ) { $i++; print $i; } print "\n";
Re^2: Searching in an array of arrays
by perl_seeker (Scribe) on Nov 04, 2004 at 08:52 UTC
    Hello zejames!
    Thanks a lot for your reply. I do not understand your code fully, please bear with me. What
    are the variables last_range and first_day used for, and what should their initial values be?

    Also for this line,
    my $range = $day->[1] - ($day->[1] % 5);
    I get this error:
    Operation `%': no method found,left argument in overloaded package XML +::XPath::Literal,right argument has no overloaded magic at C:\..\xmlr +ecord_parse.pl line 604.
    Using sprintf removes the error, but I'm not sure whether this is correct(i.e. the control string "%f"):
    my $range = sprintf("%f","$day->[1]") - (sprintf("% f","$day->[1]") % 5);
    My array of arrays @data looks like this:
    [ 1-1-2004 15.0 ], [ 2-1-2004 15.5 ], [ 3-1-2004 16.5 ], [ 4-1-2004 17.0 ], [ 5-1-2004 17.5 ], [ 6-1-2004 18.0 ], [ 7-1-2004 18.5 ], [ 8-1-2004 19.0 ], [ 9-1-2004 19.5 ], [ 10-1-2004 25.0 ], [ 11-1-2004 26.5 ], [ 12-1-2004 27.5 ], [ 13-1-2004 28.0 ], [ 14-1-2004 29.5 ], [ 15-1-2004 28.0 ], [ 16-1-2004 28.8 ],
    So the resulting array of arrays I need to build should look like this:
    1-1-2004 5-1-2004 mild 10-1-2004 14-1-2004 verywarm
    The values of $range (printing inside the loop)I'm getting are:
    15 15.5 15.5 15 15.5 15 15.5 15 15.5 25 25.5 25.5 25 25.5 25 25.8
    This statements does not print anything:
    print "$first_day $day->[0] ".$ranges{$range}."\n";
    Please help, really need it!

    Thanks,
    perl_seeker:)
      I don't understand your first problem. Testing my code here with the @data defined as :
      @data = ( [ '1-1-2004', 15.0 ], [ '2-1-2004', 15.5 ], [ '3-1-2004', 16.5 ], [ '4-1-2004', 17.0 ], [ '5-1-2004', 17.5 ], [ '6-1-2004', 18.0 ], [ '7-1-2004', 18.5 ], [ '8-1-2004', 19.0 ], [ '9-1-2004', 19.5 ], ... [ '16-1-2004', 28.8 ]);
      does work here. Could you provide code ? Your problem seems to be XML related.

      As for the range, you're right, there is problem, that is corrected in the new version, by converting temperature to an integer :
      $day->[1] = int $day->[1];

      $last_range is used to remember the current range we are in. If that range remains unchanged 5 times, we print the range information.

      $first_day is used to remember the first day we saw the temperature of the current range;

      HTH

      --
      zejames
        Hi,this is (part of)the XML file I am parsing:
        - <AnnualWeatherRecord> - <DailyWeatherRecord> <date>1-1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="15.0" /> <mindrybulb unit="degrees-centigrade" number="15.0" /> <maxwetbulb unit="degrees-centigrade" number="33.53" /> <minwetbulb unit="degrees-centigrade" number="30.53" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>2-1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="15.5" /> <mindrybulb unit="degrees-centigrade" number="15.5" /> <maxwetbulb unit="degrees-centigrade" number="23.14" /> <minwetbulb unit="degrees-centigrade" number="20.14" /> </temperature> <totalrainfall unit="mm" number="0" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>3-1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="16.5" /> <mindrybulb unit="degrees-centigrade" number="16.5" /> <maxwetbulb unit="degrees-centigrade" number="33.53" /> <minwetbulb unit="degrees-centigrade" number="30.53" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>15-1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="28.0" /> <mindrybulb unit="degrees-centigrade" number="28.0" /> <maxwetbulb unit="degrees-centigrade" number="33.53" /> <minwetbulb unit="degrees-centigrade" number="30.53" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>16-1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="28.8" /> <mindrybulb unit="degrees-centigrade" number="28.8" /> <maxwetbulb unit="degrees-centigrade" number="33.53" /> <minwetbulb unit="degrees-centigrade" number="30.53" /> </temperature> <totalrainfall unit="mm" number="0" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>1-2-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="44.25" /> <mindrybulb unit="degrees-centigrade" number="39.25" /> <maxwetbulb unit="degrees-centigrade" number="33.53" /> <minwetbulb unit="degrees-centigrade" number="30.53" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </DailyWeatherRecord> - <DailyWeatherRecord> <date>2-2-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="50.25" /> <mindrybulb unit="degrees-centigrade" number="49.25" /> <maxwetbulb unit="degrees-centigrade" number="23.14" /> <minwetbulb unit="degrees-centigrade" number="20.14" /> </temperature> <totalrainfall unit="mm" number="0" /> </DailyWeatherRecord> - <MonthlyWeatherRecord> <date>1-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="33.95" /> <mindrybulb unit="degrees-centigrade" number="23.20" /> <avgdrybulb unit="degrees-centigrade" number="33.95" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </MonthlyWeatherRecord> - <MonthlyWeatherRecord> <date>2-2004</date> - <temperature> <maxdrybulb unit="degrees-centigrade" number="50.25" /> <mindrybulb unit="degrees-centigrade" number="39.25" /> <avgdrybulb unit="degrees-centigrade" number="44.25" /> </temperature> <totalrainfall unit="mm" number="0.5" /> </MonthlyWeatherRecord> </AnnualWeatherRecord>
        And this is the code I'm using to parse it and build @data
        Subroutine
        sub MonthlyMaxTempSpellMessage{ my $month = shift; #print "\n$month"; $month = "-$month-"; #print "\n$month"; my $xp = XML::XPath->new(filename =>'weather_records.xml'); my @data=(); my $nodes = $xp->findnodes("//DailyWeatherRecord [contains(date,'$month')]"); foreach my $node($nodes->get_nodelist){ push @data, [$xp->findvalue(".//date",$node),$xp- >findvalue(".//maxdrybulb /\@number",$node)]; } for my $aref ( @data ) { print "\t [ @$aref ],\n"; }
        Main
        my $monthmts=1; MonthlyMaxTempSpellMessage($monthmts);
        Anything wrong here? What do I need to change in your code to build the required array of arrays?
        Thanks
        perl_seeker:)

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2020-10-24 18:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (246 votes). Check out past polls.

    Notices?