my %seen; for my $i (reverse (0 .. @$ref-1)) { # replaces current item in array with last item # and removes the last element if id already seen $ref->[$i] = pop @$ref if $seen{$ref->[$i]->{id}}++; } #### my %seen; my $removed = 0; for my $i (0 .. @$ref-1) { my $item = $ref->[$i]; $seen{$item->{id}}++ ? $removed++ : ($ref->[$i-$removed] = $item); } splice @$ref,-$removed;