Dear Monks,

I have a table which has two columns: the number and the previous number. There can be more than two items in the chain. I build a hash where the key is the number and the value is the very first item in the chain.

Below is my code by now (a minimal example to play with). It just works, but it is fragile, since it relies on the assumption that there is at most 5 items in the chain. In the real task it should be so, but it is not guaranteed. What would be the better way to do it?

Thanks in advance!

#!/perl use strict; use warnings FATAL => qw(all); use Text::CSV_XS; use Data::Dump; my $csv_par = { binary => 1, auto_diag => 1, allow_whitespace => 1, sep_char => ';', eol => $/, quote_char => undef, }; my $csv = Text::CSV_XS->new($csv_par); my @data = @{ $csv->getline_all(*DATA) }; shift @data; # simply throw away the header. my %main; my %first_pass; for my $row ( @data ) { $first_pass{$row->[0]} = $row->[1]; $main{$row->[0]} = $row->[1]; } my %second_pass; for my $row (@data) { if ( $first_pass{$row->[1]} ) { $second_pass{$row->[0]} = $row->[1]; $main{ $row->[0] } = $main{ $row->[1] } || $row->[1]; } } my %third_pass; for my $row (@data) { if ( $second_pass{$row->[1]} ) { $third_pass{$row->[0]} = $row->[1]; $main{ $row->[0] } = $main{ $row->[1] } || $row->[1]; } } my %fourth_pass; for my $row (@data) { if ( $third_pass{$row->[1]} ) { $fourth_pass{$row->[0]} = $row->[1]; $main{ $row->[0] } = $main{ $row->[1] } || $row->[1]; } } for my $row ( @data ) { $main{$row->[1]} = "" unless exists $main{$row->[1]} or $row->[1] eq ""; } for my $num ( sort {$a <=> $b} keys %main ) { $main{$num} = $num unless length($main{$num}); print "$num => $main{$num}$/"; } # Sample chains: # 123-234-345-456-567 # 117-228-339 # 131 # 213-324-435 # 372 __DATA__ NUM;NUMPRED 567;456 456;345 345;234 234;123 339;228 228;117 131; 435;324 324;213 372;
The output:
117 => 117 123 => 123 131 => 131 213 => 213 228 => 117 234 => 123 324 => 213 339 => 117 345 => 123 372 => 372 435 => 213 456 => 123 567 => 123

In reply to Looking for the first item in the chain by vagabonding electron

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.