The_Rev has asked for the wisdom of the Perl Monks concerning the following question:

Hello again,

I need an algorithm that will somehow parse my data sample below. and keep track of the unique hex numbers as well as a consolidated list of int values associated with each hex number

#!/perl/bin/perl.exe -w use strict; while (<DATA>) { Dynamic SortRoutine here } __DATA__ 0x130005d 1.253.54.1 11 0x130009c 1.253.54.2 12 0x130005d 1.253.54.1 14 0x130005d 1.253.54.1 11 0x130005d 1.253.54.1 10 0x130009c 1.253.54.2 12 0x130009c 1.253.54.2 14
I've tried several things such as pushing only the unique elements onto an array, but I was unable to keep track of the unique int values for each unique hex number

The desired output would be an array for each unique hex number with elements of unique int values

0x130009c = 12, 14 0x130005d = 10, 11

Replies are listed 'Best First'.
Re: Algorithm needed
by elusion (Curate) on Dec 05, 2002 at 23:14 UTC
    How's this do ya?
    #!/usr/bin/perl -w use strict; my %hash = (); while (<DATA>) { # split based on spaces my ($hex, $foo, $int) = split /\s+/; # use hash value as an array ref push @{$hash{$hex}}, $int; }
    You can then access the ints by using the hash values as array refs. For instance, to print the output:
    for (keys %hash) { print "$_ = ", join(", ", sort @{$hash{$_}}), "\n"; }

    elusion : http://matt.diephouse.com

    Update: D'oh! Missed the part about ints being unique. merlyn saw it though.

      Or, just do it all at once:
      my %hash = (); while (<DATA>) { # split based on spaces my ($hex, $foo, $int) = split /\s+/; $hash{$hex}{$int}++; } for (keys %hash) { print "$_ = ", join(", ", sort keys %{$hash{$_}}), "\n"; }

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        split /\s+/;

        Do you recommend this as normal practice? I think the special case, split ' ', is usually what people really want. (Yes, this is a very minor point but I'm curious.)

        -sauoq
        "My two cents aren't worth a dime.";
        
      It works fine, except I only need the unique ints, because my real data file is quite large.

      I.E.

      0x130005d = 10, 11, 14 0x130009c = 12, 14
      This is the same problem I was having earlier.
Re: Algorithm needed
by The_Rev (Acolyte) on Dec 05, 2002 at 23:50 UTC
    I tried the following revised code, but it neglects to push unique values onto each individual array.
    #!/usr/bin/perl -w use strict; my %seen; my %hash = (); while (<DATA>) { # split based on spaces my ($hex, $foo, $int) = split /\s+/; # use hash value as an array ref push @{$hash{$hex}}, $int unless $seen{$int}++; } for (keys %hash) { print "$_ = ", join(", ", sort @{$hash{$_}}), "\n"; } __DATA__ 0x130005d 1.253.54.1 11 0x130009c 1.253.54.2 12 0x130005d 1.253.54.1 14 0x130005d 1.253.54.1 11 0x130005d 1.253.54.1 10 0x130009c 1.253.54.2 12 0x130009c 1.253.54.2 14
      Using merlyn's code (see this node):
      use strict; my %hash; while (<DATA>) { # split based on spaces my ($hex, $foo, $int) = split /\s+/; $hash{$hex}{$int}++; } for (keys %hash) { print "$_ = ", join(", ", sort keys %{$hash{$_}}), "\n"; } __DATA__ 0x130005d 1.253.54.1 11 0x130009c 1.253.54.2 12 0x130005d 1.253.54.1 14 0x130005d 1.253.54.1 11 0x130005d 1.253.54.1 10 0x130009c 1.253.54.2 12 0x130009c 1.253.54.2 14
      Gives
      0x130005d = 10, 11, 14 0x130009c = 12, 14


      --
      "I don't intend for this to take on a political tone. I'm just here for the drugs." --Nancy Reagan