Hi ovedpo15,

The only problem to keep the original order of the input is that the data structure used in my solution, a hash, does not have a defined order. However, the solution is fairly easy: we only need to keep track of the original order one way or another.

One possible way to do that is to add an array (@ranks) as an auxiliary data structure when reading the file and then to loop over the array when preparing the output:

use strict; use warnings; use feature 'say'; my (%tree, @ranks); while (<DATA>) { chomp; my ($id, $pid, $name) = split /,/; $tree{$id} = {pid => $pid, name => $name}; push @ranks, $id; } for my $id (@ranks) { my @parent_list; my $temp_id = $id; while (exists $tree{$temp_id}) { push @parent_list, $tree{$temp_id}{name}; $temp_id = $tree{$temp_id}{pid}; } say join ",", @parent_list; } __DATA__ 15,10,name3 10,#,name1 12,10,name2 5,12,name4 8,5,name5
which produces the following output:
$ perl test_ranks.pl name3,name1 name1 name2,name1 name4,name2,name1 name5,name4,name2,name1
The solution you contemplated in your question is also relatively easy, except for the syntax used to sort the records according to the ranks, which may be regarded as a bit complicated for a Perl beginner. Here, I have added a rank field into the records and then sort the id's in accordance to the rank:
use strict; use warnings; use feature 'say'; my (%tree); while (<DATA>) { chomp; my ($id, $pid, $name) = split /,/; $tree{$id} = {pid => $pid, name => $name, rank => $.}; } for my $id (sort { $tree{$a}{rank} <=> $tree{$b}{rank} } keys %tree) { my @parent_list; my $temp_id = $id; while (exists $tree{$temp_id}) { push @parent_list, $tree{$temp_id}{name}; $temp_id = $tree{$temp_id}{pid}; } say join ",", @parent_list; } __DATA__ 15,10,name3 10,#,name1 12,10,name2 5,12,name4 8,5,name5
which produces the same output as before.

Another possible way might be to read the input file again to get the id's in the proper order, but I wouldn't recommend that as that would be less efficient.

You may also take a look at the Hash::Ordered module on the CPAN, which implements a hash data structure with a builtin order.

Update: Fixed a typo: s/reparing the output/preparing the output/.


In reply to Re^5: Reorganizing the content of a file by Laurent_R
in thread Reorganizing the content of a file by ovedpo15

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.