in reply to Re^2: Analytics on Hash Arrays
in thread Analytics on Hash Arrays

See the ternaryconditional operator for one solution.

$max = ($x < $max) ? $max : $x; # similar for min

or the postfix if:

$max = $x if ($x > $max);

Update: you may also want to pay attention to the initial value if it is not defined. Your min value may always be 0 unless you have minimum values that are less than the default value for undef.

--MidLifeXis

Replies are listed 'Best First'.
Re^4: Analytics on Hash Arrays
by yasser8@gmail.com (Novice) on Jun 24, 2015 at 15:55 UTC

    Thanks a lot for your excellent idea abouot using Conditional Operator....

    #!/usr/bin/env perl use strict; use warnings; my %h; my %d; my %ser; my %met; my $x=0; while(<DATA>){ next unless /\w/; my($server,$datetime,$metric,$value) = (split)[0,1,2,3]; $value =~ s/,//g ; my $ddhh = substr $datetime,0,13; my $dd = substr $datetime,0,10; $d{$dd }{$server}{$metric}{max} = ($x < $value) ? $value : $x; $d{$dd }{$server}{$metric}{min} = ($x > $value) ? $value : $x ; $h{$ddhh }{$server}{$metric}{max} = ($x < $value) ? $value : $x; $h{$ddhh }{$server}{$metric}{min} = ($x > $value) ? $value : $x ; $ser{$server} = 1; $met{$metric} = 1; } print "Frequency Hour:\ncollectionTime\n\n"; for my $key (sort keys %h){ print "$key "; for my $ser_key (sort keys %ser){ print "$ser_key "; for my $met_key (sort keys %met){ print " $met_key"; printf " %10s", $h{$key}{$ser_key}{$met_key}{max}; print " " +; printf " %10s", $h{$key}{$ser_key}{$met_key}{min}; print " " +; } } print "\n"; } __DATA__ server01: 2015-06-23T21:58:05-05:00 FC_IO_BY_R 13,5 +50,785 MB server01: 2015-06-23T21:58:05-05:00 FC_IO_BY_W 6,89 +2,224 MB server01: 2015-06-23T21:59:05-05:00 FC_IO_BY_R 13,5 +51,835 MB server01: 2015-06-23T21:59:05-05:00 FC_IO_BY_W 6,89 +2,339 MB server01: 2015-06-23T22:00:05-05:00 FC_IO_BY_R 13,5 +52,066 MB server01: 2015-06-23T22:00:05-05:00 FC_IO_BY_W 6,89 +2,433 MB server01: 2015-06-23T22:01:05-05:00 FC_IO_BY_R 13,5 +53,303 MB server01: 2015-06-23T22:01:05-05:00 FC_IO_BY_W 6,89 +2,590 MB server01: 2015-06-23T22:02:05-05:00 FC_IO_BY_R 13,5 +55,006 MB server01: 2015-06-23T22:02:05-05:00 FC_IO_BY_W 6,89 +2,836 MB server01: 2015-06-23T22:03:05-05:00 FC_IO_BY_R 13,5 +56,007 MB server01: 2015-06-23T22:03:05-05:00 FC_IO_BY_W 6,89 +2,961 MB server01: 2015-06-23T22:04:05-05:00 FC_IO_BY_R 13,5 +56,201 MB server01: 2015-06-23T22:04:05-05:00 FC_IO_BY_W 6,89 +3,086 MB server01: 2015-06-23T22:05:05-05:00 FC_IO_BY_R 13,5 +56,408 MB server01: 2015-06-23T22:05:05-05:00 FC_IO_BY_W 6,89 +3,208 MB server02: 2015-06-23T21:58:54-05:00 FC_IO_BY_R 13,4 +70,021 MB server02: 2015-06-23T21:58:54-05:00 FC_IO_BY_W 7,43 +1,544 MB server02: 2015-06-23T21:59:54-05:00 FC_IO_BY_R 13,4 +70,381 MB server02: 2015-06-23T21:59:54-05:00 FC_IO_BY_W 7,43 +1,642 MB server02: 2015-06-23T22:00:54-05:00 FC_IO_BY_R 13,4 +71,003 MB server02: 2015-06-23T22:00:54-05:00 FC_IO_BY_W 7,43 +1,760 MB server02: 2015-06-23T22:01:54-05:00 FC_IO_BY_R 13,4 +71,334 MB server02: 2015-06-23T22:01:54-05:00 FC_IO_BY_W 7,43 +1,980 MB server02: 2015-06-23T22:02:54-05:00 FC_IO_BY_R 13,4 +71,629 MB server02: 2015-06-23T22:02:54-05:00 FC_IO_BY_W 7,43 +2,196 MB server02: 2015-06-23T22:03:54-05:00 FC_IO_BY_R 13,4 +71,947 MB server02: 2015-06-23T22:03:54-05:00 FC_IO_BY_W 7,43 +2,307 MB server02: 2015-06-23T22:04:54-05:00 FC_IO_BY_R 13,4 +72,575 MB server02: 2015-06-23T22:04:54-05:00 FC_IO_BY_W 7,43 +2,418 MB server02: 2015-06-23T22:05:54-05:00 FC_IO_BY_R 13,4 +73,473 MB server02: 2015-06-23T22:05:54-05:00 FC_IO_BY_W 7,43 +2,586 MB

    Maximum values are fine, but as you said I am struck with Minimum values defined, its always getting initialized to 0.

    Could you please help me to come out of it? I mean, is there any way to initialize the actual minimum values?

      You were using the same variable $x for max and min, and never updating it, nor comparing with the current max value for a $server and $metric combination. I'm surprised either max or min was correct. I suggest an alternative approach.

      while(<DATA>){ next unless /\w/; my($server,$datetime,$metric,$value) = (split)[0,1,2,3]; $value =~ s/,//g ; my $ddhh = substr $datetime,0,13; my $dd = substr $datetime,0,10; if (! defined($d{$dd }{$server}{$metric}{max})) { $d{$dd }{$server}{$metric}{max} = 0; $d{$dd }{$server}{$metric}{min} = 99999999; $h{$ddhh }{$server}{$metric}{max} = 0; $h{$ddhh }{$server}{$metric}{min} = 99999999; } $d{$dd }{$server}{$metric}{max} = $value if ($d{$dd }{$serve +r}{$metric}{max} < $value); $d{$dd }{$server}{$metric}{min} = $value if ($d{$dd }{$serve +r}{$metric}{min} > $value); $h{$ddhh }{$server}{$metric}{max} = $value if ($h{$ddhh }{$serve +r}{$metric}{max} < $value); $h{$ddhh }{$server}{$metric}{min} = $value if ($h{$ddhh }{$serve +r}{$metric}{min} > $value); $ser{$server} = 1; $met{$metric} = 1; }
      Dum Spiro Spero

        Confused...My previous code just traverse till the end of DATA and just displays the end data. Its not performing what I am willing to do.

        my $x=0; while(<DATA>){ next unless /\w/; my($server,$datetime,$metric,$value) = (split)[0,1,2,3]; $value =~ s/,//g ; my $ddhh = substr $datetime,0,13; my $dd = substr $datetime,0,10; $d{$dd }{$server}{$metric}{max} = ($x < $value) ? $value : $x; $d{$dd }{$server}{$metric}{min} = ($x > $value) ? $value : $x ; $h{$ddhh }{$server}{$metric}{max} = ($x < $value) ? $value : $x; $h{$ddhh }{$server}{$metric}{min} = ($x > $value) ? $value : $x ; $ser{$server} = 1; $met{$metric} = 1; }

        In above code $x < $value always holds true and just traverse till end of DATA...it doesn't find the maximum value. If you don't mind can you please provide me the pseudo-code OR any hints to achieve it?