use warnings; use strict; use Data::Dump::Streamer; my @word = map { lc } qw" the in of to that "; # solution in OP my %x; for (my @w = @word) { s/(.)/\{\1\}/g; eval("\$x${_}{EOS}++"); } Dump(\%x); # module use Data::Diver "DiveVal"; my %y; for (@word) { DiveVal(\%y, split(//, $_), "EOS")++; } Dump(\%y); # by hand my %z; for (@word) { my $t = \%z; for my $k ($_ =~ /./gs) { $t = \%{$$t{$k}} } $$t{EOS}++; } Dump(\%z); __END__ #### \1 better written as $1 at a.pl line 10. $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } }; $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } }; $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } };