Operating System - Linux
1748167 Members
4063 Online
108758 Solutions
New Discussion юеВ

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

 
SOLVED
Go to solution
Pankaj Yadav_1
Frequent Advisor

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 .
10 REPLIES 10
James R. Ferguson
Acclaimed Contributor
Solution

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...
Victor Fridyev
Honored Contributor

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
Hein van den Heuvel
Honored Contributor

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.
Pankaj Yadav_1
Frequent Advisor

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.
James R. Ferguson
Acclaimed Contributor

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...
Hein van den Heuvel
Honored Contributor

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.
Pankaj Yadav_1
Frequent Advisor

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.
Ralph Grothe
Honored Contributor

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
Pankaj Yadav_1
Frequent Advisor

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.