use strict; use warnings; use Data::Dumper; my %dependencies; while () { chomp; my ($key, @items) = split /,/; $dependencies{$key} = [@items]; } # print Dumper \%dependencies; my $continue = 1; while ($continue) { $continue = 0; for my $key (keys %dependencies) { my @jobs = @{$dependencies{$key}}; my %seen = map { $_ => 1 } @jobs; my @add; for my $job (@jobs) { next unless exists $dependencies{$job}; my @new_jobs = @{$dependencies{$job}}; for my $new_job (@new_jobs) { next if exists $seen{$new_job}; $continue = 1; push @add, $new_job; $seen{$new_job} = 1; } } push @{$dependencies{$key}}, @add; } } print Dumper \%dependencies; __DATA__ job1, job2,job1, job3,job2 job4,job2 job5,job2,job4 job6,jobz joba,job4,jobb jobz,jobbc,job2 #### $VAR1 = { 'job3' => [ 'job2', 'job1' ], 'jobz' => [ 'jobbc', 'job2', 'job1' ], 'job6' => [ 'jobz', 'jobbc', 'job2', 'job1' ], 'job4' => [ 'job2', 'job1' ], 'joba' => [ 'job4', 'jobb', 'job2', 'job1' ], 'job5' => [ 'job2', 'job4', 'job1' ], 'job1' => [], 'job2' => [ 'job1' ] };