Hi,

I have a data file in which holds information on different items accorded to individual users. A user might have more than one item (each one being unique), in which case he is accorded a new line for each item.

Users with multiple items are treated differently to those with just the one and so I am trying to group together the lines for each user and then trat them on a case by case basis.

I have written the following code which does seem to do the trick, but I would like advice and comments from my fellow monks on how I could do it better (and to ensure that I'm not fluking the results and thus saving up problems for the future.

I have commented the code to try to explain my thought process (just in case you thought there wasn't one!! )

Any help given would be much appreciated.

open PAGE, "$website" or die "Cant open $website: $!"; flock (PAGE, 1) or die "Can't lock website file for reading"; while (my $line = (<PAGE>)) { ($Prop,$colour,$txtcol,$url360,$user,$your_name,$address,$town,$zip_co +de,$country,$email,$telephone_no,$telephone_no2,$theme,$web_address,$ +ppemail,undef,undef,undef) = split "\t", $line; #create array of users and hash of data $onprop{$Prop} = [$Prop,$colour,$txtcol,$url360,$user,$your_name,$ +address,$town,$zip_code,$country,$email,$telephone_no,$telephone_no2, +$theme,$web_address,$ppemail]; push (@dataarray, $user); } #iterate over users while (<@dataarray>) { my @microdata; #remove examine first user my $item = shift (@dataarray); foreach my $scalar (keys %onprop) { unless (! $item) { #compare lines of hash looking for lines with same user if ( @{ $onprop{ $scalar } }[4] eq $item) { #if found, remove from array my $a = shift(@dataarray); push (@microdata, @{ $onprop{ $scalar } }); } } } #store all results for this owner in single reference my $refmicro = \@microdata; push (@group, $refmicro); } foreach (@group) { print "@{ $_ }<br><br>"; }
Update: I enclose a rewrite of the code including data to make it easier to view the results. I knew before I'd posted that what I'd done was 'clunky' but I wanted to get something working before I came looking for help...
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use CGI ':standard'; #definitions: #========= my ( $Prop, $colour, $txtcol, $url360, $user, $your_name, $address, $town, $zip_code, $country, $email, $telephone_no, $telephone_no2, $theme, $web_address, $ppemail ); my %onprop; my @dataarray; my @group; print "Content-type: text/html\n\n"; while (my $line = (<DATA>)) { ($Prop,$colour,$txtcol,$url360,$user,$your_name,$address,$town,$zip_co +de,$country,$email,$telephone_no,$telephone_no2,$theme,$web_address,$ +ppemail,undef,undef,undef) = split "\t", $line; #create array of users and hash of data $onprop{$Prop} = [$Prop,$colour,$txtcol,$url360,$user,$your_name,$ +address,$town,$zip_code,$country,$email,$telephone_no,$telephone_no2, +$theme,$web_address,$ppemail]; push (@dataarray, $user); } #iterate over users while (<@dataarray>) { my @microdata; #remove examine first user my $item = shift (@dataarray); foreach my $scalar (keys %onprop) { unless (! $item) { #compare lines of hash looking for lines with same user if ( @{ $onprop{ $scalar } }[4] eq $item) { #if found, remove from array my $a = shift(@dataarray); push (@microdata, @{ $onprop{ $scalar } }); } } } #store all results for this owner in single reference my $refmicro = \@microdata; push (@group, $refmicro); } foreach (@group) { print "@{ $_ }<br><br>"; } __DATA__ 012 undef undef undef graham undef u +ndef undef undef undef undef 037 undef undef graham undef undef undef unde +f undef undef undef undef undef 028 red tdblk johnandmark undef undef undef +undef undef undef undef undef 108 yellow tdblk undef johnandmark undef undef u +ndef undef UK undef undef undef undef + 013 blue tdblk undef jon undef undef undef un +def undef undef undef undef undef undef undef + 008 blue tdblk malcolm undef undef undef unde +f undef undef undef undef 133 green tdblk sharon undef undef undef unde +f uk undef undef undef undef undef 047 blue tdblk gill undef undef undef undef + undef undef undef undef undef
Further Update: This site never ceases to amaze - so many people give freely of their time and advice. I'm grateful for the knowledge that has been imparted - I feel much better armed to go away and write a more robust and incisive script for the task I have in mind. Thanks to all.

In reply to grouping lines of data together for later use by jonnyfolk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.