Search code examples
perl

Remove values from array inside a hash


I have a hash %m_h with a couple of different data types inside. I want to remove the item 'q20_bases' from the array in $VAR4 but can't figure out how.

Data Structure (From print Dumper %m_h)

$VAR1 = 'run_m';
$VAR2 = [
          'run_id',
          'machine',
          'raw_clusters',
          'passed_filter_reads',
          'yield'
        ];
$VAR3 = 'ln_m';
$VAR4 = [
          'run_id',
          'lane_number',
          'read_number',
          'length',
          'passed_filter_reads',
          'percent_passed_filter_clusters',
          'q20_bases',
          'q30_bases',
          'yield',
          'raw_clusters',
          'raw_clusters_sd',
          'passed_filter_clusters_per_tile',
          'passed_filter_clusters_per_tile_sd',
          'percent_align',
          'percent_align_sd'
        ];

I tried delete $m_h{'q20_bases'}; though it did nothing and I'm not sure what direction to head in.


Solution

  • delete removes a key and the associated value from a hash, not an element from an array.

    You can use grep to select the elements of the array that are different to q20_bases.

    $m_h{ln_m} = [grep $_ ne 'q20_bases', @{ $m_h{ln_m} }];
    

    or

    @{ $m_h{ln_m} } = grep $_ ne 'q20_bases', @{ $m_h{ln_m} };
    

    You can also use splice to remove an element from an array, but you need to know its index:

    my ($i) = grep $m_h{ln_m}[$_] eq 'q20_bases', 0 .. $#{ $m_h{ln_m} };
    splice @{ $m_h{ln_m} }, $i, 1;
    

    You can see that you always need to dereference the value with @{...} to get the array from the array reference. Recent Perls also provide an alternative syntax for it:

    $m_h{ln_m}->@*