http://qs321.pair.com?node_id=11124476


in reply to Organizing data from a hash

Fun little problem - just stick the parents in front of the children and clean it up at the end :)

#!/usr/bin/perl use strict; use warnings; use List::Util qw( uniq ); my $data = { 986172 => { cat_name => "Category1", cat_parent_id => "" }, 986176 => { cat_name => "Category2", cat_parent_id => 986172 }, 986177 => { cat_name => "Category3", cat_parent_id => 986176 }, 986178 => { cat_name => "Category4", cat_parent_id => 986177 }, }; my $string = join ',', find( keys %$data ); print "$string\n"; sub find { uniq map { my $ref = $data->{$_}; $ref ? ( find( $ref->{cat_parent_id} ), $ref->{cat_name} ) : () } @_; }

Or build a little prerequisite table and topologically extract the names one by one.

#!/usr/bin/perl use strict; use warnings; my $data = { 986172 => { cat_name => "Category1", cat_parent_id => "" }, 986176 => { cat_name => "Category2", cat_parent_id => 986172 }, 986177 => { cat_name => "Category3", cat_parent_id => 986176 }, 986178 => { cat_name => "Category4", cat_parent_id => 986177 }, }; my $parents = ''; for my $v ( values %$data ) { $parents .= $v->{cat_parent_id} ? $v->{cat_name} . ' ' . $data->{$v->{cat_parent_id}}{cat_name} . + "\n" : $v->{cat_name} . "\n"; } #print "$parents\n"; my @order; $parents =~ s/\b($1)\b//g, push @order, $1 while $parents =~ s/^(\w+)\ +h*\n//m; my $answer = join ',', @order; print "$answer\n"; $parents and die "loop in parents at\n$parents";