use warnings; use strict; use Data::Dumper; my @array = qw/ comp1-cmd1-test1 comp1-cmd1-test2 comp1-cmd2-test1 comp2-cmd1-test1 comp2-cmd1-test2 comp3-cmd1-test1/; my $hash = {}; for my $element (@array) { my @stuffs = split /-/, $element; insert($hash, \@stuffs); } print Dumper($hash); sub insert { my ($hash, $stuffs) = @_; my $first_element = shift @$stuffs; $hash->{$first_element} = {} if (!defined($hash->{$first_element})); insert($hash->{$first_element}, $stuffs) if (@$stuffs); }