http://www.perlmonks.org?node_id=1008187

sfrisch@mt.gov has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to print the keys and the values of a hash of array using a data structure. I would like to it sorted by key.<\p>

I have got the array set up at least I think I do I have all kinds of print statments telling me that I am not too crazy. I would like to have a print out that looks like the following only soted by the second -- or first fields.

Input

DOABIL3020 ITSD-ENT_OP-DMSB-DIDS Ora

DOABIL309 EXE-SOS-3201_DFLT Ora

DOABIL3400 ITSD-ENT_OP-ETSB-MID PRD

DOABIL5310 ITSD-ENT_OP-ETSB-MID TST

DOABIL6230 EXE-SOS-3201_DFLT PRD

DOABIL7001 ITSD-ENT_OP-ETSB-EAS PRD

DOABIL7005 ITSD-ENT_OP-AIMB-DCSEC PRD

DOABIL7006 ITSD-ENT_OP-AIMB-DCSEC PRD

DOABIL7504 EXE-SOS-3201_DFLT PRD

DOABIL7581 ITSD-ENT_OP-NTSB-NET PRD

DOABIL7582 ITSD-ENT_OP-NTSB-NET PRD

DOABIL7583 ITSD-ENT_OP-NTSB-NET PRD

Out put is the same only sorted that is what I am shooting for.

open INTO,">sumfile.txt"; open FILE, "serverinventory.txt"; while(<FILE>){ chomp; $_ =~ s/\"//g; #$_=~ s/\,/ /g; @LINE=split(/\,/); $HOST=$LINE[1]; if($HOST =~/DOAISDBLADE/|| $HOST =~ /DOAISD9/|| $HOST =~/K +VM/|| $HOST =~/DOABILBLA/){ } elsif($LINE[19] =~ /EXE/||$LINE[19] =~ /ITSD/||$LINE[19] = +~/REV/){ $FMM = $LINE[19]; $USE = $LINE[16]; $HOST = $LINE[1]; my $USE = substr($USE,0,3); my $AG = substr($LINE[16],4,17); #printf INTO ("%0s %0s\n",$FMM,$HOST,$USE); print INTO "$HOST $FMM $USE\n"; } } close FILE; close INTO; # MOVe to running against the new file made sumery.txt open FILE2,"sumfile.txt"; open too,">out.txt"; # open file for counts to be depposited to while(<FILE2>){ chomp; @arry1 = split(/ /); $TOTAL = $tab1=$arry1[0]; $tab2=$arry1[1]; #print "$tab1 $tab2\n"; push(@ {$ARG{"$tab1"}},"$tab2"); } # foreach $string (keys %ARG) { #HASH OF ARRAY SORTED $last = $#{$ARG{$string}}; #GETS THE COUNT OF THE JOBS FOR +EACH TABLE $last=$last + 1; print "$string $ARG{$string}\n"; }

I get a print of the keys but not the value. So I do not understand how to get to all tyhe data I am generating.<\p>

Replies are listed 'Best First'.
Re: Accessing or printing key and value
by GrandFather (Saint) on Dec 11, 2012 at 01:20 UTC

    Your code, your sample data and your question are so far apart that in the end I decided to ignore your code and produced the following sample for you to consider:

    use strict; use warnings; my %jobs; while (<DATA>) { chomp; next if ! /\S/; my @parts = split; push @{$jobs{$parts[1]}}, $_; } print "$_\n" for map {join "\n", @{$jobs{$_}}} sort keys %jobs; __DATA__ DOABIL3020 ITSD-ENT_OP-DMSB-DIDS Ora DOABIL309 EXE-SOS-3201_DFLT Ora DOABIL3400 ITSD-ENT_OP-ETSB-MID PRD DOABIL5310 ITSD-ENT_OP-ETSB-MID TST DOABIL6230 EXE-SOS-3201_DFLT PRD DOABIL7001 ITSD-ENT_OP-ETSB-EAS PRD DOABIL7005 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7006 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7504 EXE-SOS-3201_DFLT PRD DOABIL7581 ITSD-ENT_OP-NTSB-NET PRD DOABIL7582 ITSD-ENT_OP-NTSB-NET PRD DOABIL7583 ITSD-ENT_OP-NTSB-NET PRD

    Prints:

    DOABIL309 EXE-SOS-3201_DFLT Ora DOABIL6230 EXE-SOS-3201_DFLT PRD DOABIL7504 EXE-SOS-3201_DFLT PRD DOABIL7005 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7006 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL3020 ITSD-ENT_OP-DMSB-DIDS Ora DOABIL7001 ITSD-ENT_OP-ETSB-EAS PRD DOABIL3400 ITSD-ENT_OP-ETSB-MID PRD DOABIL5310 ITSD-ENT_OP-ETSB-MID TST DOABIL7581 ITSD-ENT_OP-NTSB-NET PRD DOABIL7582 ITSD-ENT_OP-NTSB-NET PRD DOABIL7583 ITSD-ENT_OP-NTSB-NET PRD

    I can't tell which field you really want to sort on so I took a guess.

    As others have suggested: you should always use strictures (use strict; use warnings;). Also, remove code that is no longer relevant (use a revision control system if you think you may need to go back to a past version of the code) and find an indentation scheme that works for you and stick with it. Consistent and accurate indentation can make your code much easier to understand!

    True laziness is hard work
Re: Accessing or printing key and value
by ww (Archbishop) on Dec 11, 2012 at 00:49 UTC
    The close-curly on Ln 15 terminates your if clause... but there's no body to the if block. No code means the first if test is a nullity.

    If that first conditional fails, the code falls thru to the elsif.

    Pls explain why your code at Ln 40, open too,">out.txt";   # open file for counts to be depposited to, is unlike your other (reasonably well-formed opens.

    It appears that you're using neither strict nor warnings. Both would help you find your own syntax mistakes. Your localization (or Not) of variables is inconsistent. Your $ARG variable tromps all over it's conventional usage:

    $ARG $_ The default input and pattern-searching space.
    (per perlvar)

    Your indentation is idiosyncratic (at the kindest) and erratic. Single-tab (or 2 to 4 space) indents for each level of curlies would make this code far easier to read.

    ... and so far, nothing here explicitly addresses your question. That's deliberate. Please, when you post code, make sure it's runnable (or at least passes a compile test with strict in force. And, please, put your data inside code tags, so there's no question about the actual content of the data.. If you fix these problems, you'll find the Monks most generous in helping you learn.

Re: Accessing or printing key and value
by frozenwithjoy (Priest) on Dec 11, 2012 at 00:38 UTC

    The way you are loading your hash looks odd. I suggest putting something this into your loop: $ARG{$tab1} = $tab2; instead of push(@ {$ARG{"$tab1"}},"$tab2");. (EDIT: nevermind about that, I just realized you are going for a hash of arrays) Also, be sure to include use warnings; use strict;, if you aren't already doing so.

    As I understand it, the column you want to sort by is also the key, right? If so, change foreach  $string  (keys %ARG) { to foreach $string ( sort keys %ARG ) { (otherwise, the order will be 'random').

Re: Accessing or printing key and value
by 2teez (Vicar) on Dec 11, 2012 at 01:22 UTC

    Hi sfrisch@mt.gov.
    Please, I might be wrong here, but I don't see any "correlation" between the first part of your code and the input given.
    However, the second part staring from this line:

    # MOVe to running against the new file made sumery.txt open FILE2,"sumfile.txt"; ...
    Suggested to me that the "input" given here should be data in your sumfile.txt file. To which you needed to sort.
    If the above is correct and this "Out put is the same only sorted that is what I am shooting for.".

    I think a Schwartzian Transform could work for you like so:
    #!/usr/bin/perl use warnings; use strict; my @data_array; while (<DATA>) { chomp; next if $_ eq ''; push @data_array, $_; } print map { $_->[0], $/ } sort { $a->[1] <=> $b->[1] } map { /.+?([0-9]+?)\s/; [ $_, $1 ] } @data_array; __DATA__ DOABIL3020 ITSD-ENT_OP-DMSB-DIDS Ora DOABIL309 EXE-SOS-3201_DFLT Ora DOABIL3400 ITSD-ENT_OP-ETSB-MID PRD DOABIL5310 ITSD-ENT_OP-ETSB-MID TST DOABIL6230 EXE-SOS-3201_DFLT PRD DOABIL7001 ITSD-ENT_OP-ETSB-EAS PRD DOABIL7005 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7006 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7504 EXE-SOS-3201_DFLT PRD DOABIL7581 ITSD-ENT_OP-NTSB-NET PRD DOABIL7582 ITSD-ENT_OP-NTSB-NET PRD DOABIL7583 ITSD-ENT_OP-NTSB-NET PRD
    Output:
    DOABIL309 EXE-SOS-3201_DFLT Ora DOABIL3020 ITSD-ENT_OP-DMSB-DIDS Ora DOABIL3400 ITSD-ENT_OP-ETSB-MID PRD DOABIL5310 ITSD-ENT_OP-ETSB-MID TST DOABIL6230 EXE-SOS-3201_DFLT PRD DOABIL7001 ITSD-ENT_OP-ETSB-EAS PRD DOABIL7005 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7006 ITSD-ENT_OP-AIMB-DCSEC PRD DOABIL7504 EXE-SOS-3201_DFLT PRD DOABIL7581 ITSD-ENT_OP-NTSB-NET PRD DOABIL7582 ITSD-ENT_OP-NTSB-NET PRD DOABIL7583 ITSD-ENT_OP-NTSB-NET PRD
    I sorted using the first column.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me