Re: How to find the minimum value in an array in PERL (876 Views)
Reply
Frequent Advisor
Pankaj Yadav_1
Posts: 54
Registered: ‎08-03-2006
Message 1 of 11 (876 Views)
Accepted Solution

How to find the minimum value in an array in PERL

Hi,

My values in an array are in the form hours:mins:secs.
I want to find the minimum of these values.

Please answer me .
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 2 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Hi:

This builds on what I showed you yesterday.

# cat ./findmin
#!/usr/bin/perl
use strict;
use warnings;
my @times = ( "91:02:03", "02:11:17", "00:08:11", "03:33:33" );
my $idx = -1;
my $minidx = 0;
my $mintime = 0;
for my $t (@times) {
$idx++;
my ($hr, $min, $sec) = split /:/, $t;
my $elapsed = ($hr * 3600) + ($min * 60) + $sec;
$mintime = $elapsed if $mintime == 0;
if ($elapsed < $mintime) {
$mintime = $elapsed;
$minidx = $idx;
}
}
print "mininum is $times[$minidx] at element $minidx\n";
1;

...I have used a list (array) called "@times" with four 0-relative elements in the format "hh:mm:ss".

We iterate over the list, converting each element into a number of seconds. We track the index number of the array along with the smallest value (in seconds).

At the end, we simply print the "hh:mm:ss" and the element number that represents the minimum.

# ./findmin
mininum is 00:08:11 at element 2

Regards!

...JRF...
Honored Contributor
Victor Fridyev
Posts: 937
Registered: ‎07-01-1998
Message 3 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Try to sort the array and take the first element

HTH
Entities are not to be multiplied beyond necessity - RTFM
Honored Contributor
Hein van den Heuvel
Posts: 6,588
Registered: ‎05-19-2003
Message 4 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

The solution JRF is more resource effective than sorting, and also delivers the position of the min value in the original array.
If the is usefull for you, or if you also need to pick up the max then walk teh list as indicated.

If it is a modest size list (thousands, not millions) then as Victor indicates, just sort the array.

Example:
use strict;
use warnings;
my @times = ( "91:02:03", "02:11:17", "00:08:11", "03:33:33" );
my @sorted_times = sort @times;
print join(' - ', @sorted_times), "\n";
print "min = $sorted_times[0]\n";
print "max = $sorted_times[@sorted_times - 1]\n";

Cheers,
Hein.
Frequent Advisor
Pankaj Yadav_1
Posts: 54
Registered: ‎08-03-2006
Message 5 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

The array has value in the form of hrs:mins:secs

Will the direct sort work or we have to convert the values in seconds and then sort using the sort function.
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 6 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Hi (again):

The answer to your last question of whether or not a direct sort will work, or whether you will have to first convert to seconds, depends upon your data. Consider:

# perl -le '@a=qw(1:17:19 01:17:17 1:33:48 01:34:48);print for sort (@)'

01:17:17
01:34:48
1:17:19
1:33:48

...is *not* ordered the way you want; but:

# perl -le '@a=qw(1:17:19 1:17:17 1:33:48 1:34:48);print for sort (@a)'

...is ordered correctly.

Thus, it is simpler to convert to epoch seconds; walk through the array; and track the mininimum value and index of the original data. Of course, a more complicated sort can be written if that was the goal in the first place.

Regards!

...JRF...
Honored Contributor
Hein van den Heuvel
Posts: 6,588
Registered: ‎05-19-2003
Message 7 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Right, I used a implies string sort which relies on a consisten format. If the format is not exactly predictable, then you need to convert to formatted string, or to numeric first.
You can tell sort to use a function to do all that:

use strict;
use warnings;

sub seconds{
my ($hr, $min, $sec) = split /:/, $_[0];
return ($hr * 3600) + ($min * 60) + $sec;
}

my @times = qw(1:17:19 01:17:17 1:33:48 01:34:48);
my @sorted_times = sort @times;
print join(' - ', @sorted_times), "\n";
print "min - $sorted_times[0]\n";
print "max - $sorted_times[@sorted_times - 1]\n\n";

@sorted_times = sort {&seconds($a) <=> &seconds($b)} @times;
print join(' - ', @sorted_times), "\n";
print "min = $sorted_times[0]\n";
print "max = $sorted_times[@sorted_times - 1]\n";


fwiw,
Hein.
Frequent Advisor
Pankaj Yadav_1
Posts: 54
Registered: ‎08-03-2006
Message 8 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Thanks for all help on sorting.

Please help me on the following code-->

while(my $data = $sth->fetchrow_hashref) {
my %loopdata;
($Hrs,$Mins,$Secs) = &diffDateTime($data->{'date'},$data->{'time_in'},$data->{'time_out'},$data->{'date_out'});
$loopdata{'type'}=$data->{'type'};
$loopdata{'interval'}= "$Hrs:$Mins:$Secs";
push(@intlist, \%loopdata);

}


Please tell me whether the code is correct.
Honored Contributor
Ralph Grothe
Posts: 2,631
Registered: ‎04-09-2000
Message 9 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

Only you can tell.
First does it compile by now without raising sysntax errors and warnings?
Run perl -cw on your script.
But this won't tell if the code executes correctly.
We don't know the database's table you are querying, and therefore cannot tell whether the field names you used as keys to your result set are ok.
I would suggest you run your code in the Perl debugger and have a look at what $data contains after each fetch.
Alternatively you could use Data::Dumper or YAML, but using the debugger is easier.
perl -d /your/script.pl
will lead you into a debug session.
Continue to the first statement in the while loop (c line#).
There have a look at $data in all its beauty
|x $data
This will clarify the structure of your hash.
You can step through your code by just hitting Return, and repeat the data dump.
Madness, thy name is system administration
Frequent Advisor
Pankaj Yadav_1
Posts: 54
Registered: ‎08-03-2006
Message 10 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

My code is like this -->

my $con_sql = "SELECT type,date,time_in,time_out,date_out ".
"FROM contract_log,contract_times WHERE ".
"contract_log.refid=contract_times.conid AND date BETWEEN '$fromDate' AND '$toDate' AND date_out<>'0000-00-00'";
my $dbh = &TpsUtils::db_connect();
my $sth = $dbh->prepare($con_sql);
die "Error with SQL: $con_sql" if !defined $sth->execute;

my @intlist;
my ($Hrs,$Mins,$Secs);
use Data::Dumper;
open(FILE,'>/home/pankaj/report/test.txt');

#store the time intervals in the array @intlist
while(my $data = $sth->fetchrow_hashref) {
my %loopdata;
($Hrs,$Mins,$Secs) = &diffDateTime($data->{'date'},$data->{'time_in'},$data->{'time_out'},$data->{'date_out'});
$loopdata{'type'}=$data->{'type'};
$loopdata{'interval'}= "$Hrs:$Mins:$Secs";
push(@intlist, \%loopdata);

}

print FILE Dumper(\@intlist);


When I run the query directly I get data but when I dump that data(@intlist) in a file I can't find any data.

Please tell me whats going wrong.
Frequent Advisor
Pankaj Yadav_1
Posts: 54
Registered: ‎08-03-2006
Message 11 of 11 (876 Views)

Re: How to find the minimum value in an array in PERL

ok no need to apply your brain.
I am getting what I want.
Thanks a lot .
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.