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/.
|