#This bit works foreach (@{$row_data{groups}}){ push @{$new_row_data{groups}}, $_ if ${$_}{whatever}==$something_else; foreach (@{$row_data{fields}}){ push @{$new_row_data{fields}}, $_ if ${$_}{whatever}==$something_else; #This bit doesn't at all $row_data{groups}=$new_row_data{groups}; $row_data{fields}=$new_row_data{fields};