use Data::Dump qw(pp); my @array = qw<1000 1000 1000 1010 1010 1010 1020 1022 1023>; my %out; while (my ($pos, $val) = each @array) { $out{$val.':'.$pos} = { One => 1, Two => 1 }; } pp \%out; __END__ { "1000:0" => { One => 1, Two => 1 }, "1000:1" => { One => 1, Two => 1 }, "1000:2" => { One => 1, Two => 1 }, "1010:3" => { One => 1, Two => 1 }, "1010:4" => { One => 1, Two => 1 }, "1010:5" => { One => 1, Two => 1 }, "1020:6" => { One => 1, Two => 1 }, "1022:7" => { One => 1, Two => 1 }, "1023:8" => { One => 1, Two => 1 }, } #### my %out; my %index; my $precision = 10; for my $val (@array) { my $rounded = $precision*(int($val/$precision)); die "Too many duplicates" if exists $index{$rounded} and $index{$rounded} == $precision; my $timestamp = $rounded + $index{$rounded}++; $out{$timestamp} = { One => 1, Two => 1 }; } pp \%out; __END__ { 1000 => { One => 1, Two => 1 }, 1001 => { One => 1, Two => 1 }, 1002 => { One => 1, Two => 1 }, 1010 => { One => 1, Two => 1 }, 1011 => { One => 1, Two => 1 }, 1012 => { One => 1, Two => 1 }, 1020 => { One => 1, Two => 1 }, 1021 => { One => 1, Two => 1 }, 1022 => { One => 1, Two => 1 }, }