#! perl -slw use strict; my %hash = ( MEX1J => { desc => 'Job 2', pred => [ 'TEX1J' ], }, MEX2J => { desc => 'Job end', pred => [ qw[TEX1J MEX1J] ], }, TEX1J => { desc => 'Job start', pred => [], } ); my @orderedKeys = sort{ return 0 unless @{ $hash{ $a }{ pred } } or @{ $hash{ $b }{ pred } }; my $AinB = grep /$a/, @{ $hash{ $b }{ pred } }; my $BinA = grep /$b/, @{ $hash{ $a }{ pred } }; die "Circular dependacy $a:$b" if $AinB and $BinA; return -1 if $AinB; return 1 if $BinA; return 0 unless $AinB or $BinA; } keys %hash; print "$_ $hash{ $_ }{ desc } @{ $hash{ $_ }{ pred } }" for @orderedKeys; __END__ P:\test>500240 TEX1J Job start MEX1J Job 2 TEX1J MEX2J Job end TEX1J MEX1J #### #! perl -slw use strict; use List::Util qw[first]; my %hash = ( MEX1J => { desc => 'Job 2', pred => [ 'TEX1J' ], }, MEX2J => { desc => 'Job end', pred => [ qw[TEX1J MEX1J] ], }, TEX1J => { desc => 'Job start', pred => [], } ); my %cache; my @orderedKeys = sort{ return 0 unless @{ $hash{ $a }{ pred } } or @{ $hash{ $b }{ pred } }; my $AinB = $cache{ "$a|$b" } ||= first{ /$a/ } @{ $hash{ $b }{ pred } }; my $BinA = $cache{ "$b|$a" } ||= first{ /$b/ } @{ $hash{ $a }{ pred } }; die "Circular dependacy $a:$b" if $AinB and $BinA; return -1 if $AinB; return 1 if $BinA; return 0 unless $AinB or $BinA; } keys %hash; print "$_ $hash{ $_ }{ desc } @{ $hash{ $_ }{ pred } }" for @orderedKeys; __END__ P:\test>500240 TEX1J Job start MEX1J Job 2 TEX1J MEX2J Job end TEX1J MEX1J