in reply to Re: Extracting elements from array
in thread Extracting elements from array

I explained it wrong I guess, but using map is cool. The problem is that I also need the data as this in the end:
[ {name => "PA1"}, {name => "PB3"},... ]

Thanks where I am stuck, thanks!

Replies are listed 'Best First'.
Re^3: Extracting elements from array
by poj (Abbot) on Jan 14, 2016 at 22:03 UTC
    .. also need ..
    my @hash_names = map{ {name=>$_} } @all_names;
    poj
Re^3: Extracting elements from array
by tangent (Parson) on Jan 14, 2016 at 22:04 UTC
    my @all_names = map { {name => $_->{name}} } @{ $data }[1 .. $#$data];
      This line works, but
      my @all_names = map { {name => $_->{name}} } @{ $data }[1 .. $#$data];

      I just need some explaining in how different one line of code is from another, why wouldn't the name=>"Accounts" be picked up by the code here:
      use warnings; use strict; use Data::Dumper; my $data = [ { val => "action", name => "Accounts", id => "None", }, { name => "PA1", id => "AUTOB" }, { name => "PB3", id => "AUTOP" }, { name => "BOX", id => "BOP" }, { name => "DW0", id => "DFIRE" }, { name => "QW3", id => "HOME" }, { name => "CM7", id => "CUMBR" }, { name => "BR1", id => "PUMBR" }, { name => "TY6", id => "ECUST" }, ] ; #my @all_names = map { $_->{name} } @{ $data }[1 .. $#$data]; #my @hash_names = map{ {name=>$_} } $data; my @all_names = map { {name => $_->{name}} } @{ $data }[1 .. $#$data]; print Dumper(\@all_names); #print Dumper \@hash_names; __END__
      Such a good answers , thanks!
        why wouldn't the name=>"Accounts" be picked up
        Because you start at element #1, not 0:
        [1 .. $#$data]; ^ | | Here!
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        why wouldn't the name=>"Accounts" be picked up
        In your original data the first element of the array is unwanted so toolic has @{ $data }[1 .. $#$data] which has the effect of skipping that first element. Arrays are indexed from "0" so the first element is $array[0], the second element is $array[1] and so on. So, @{ $data }[1 .. $#$data] means the range of elements starting at the second element and up to the last element.

        A better way might be to use grep in combination with map:

        my @all_names = map { {name => $_->{name}} } grep { exists $_->{name} } @$data;
        Here grep first filters all the elements, discarding any which don't have a 'name' key, and then map constructs the desired data structure from the remaining elements.
Re^3: Extracting elements from array
by 1nickt (Canon) on Jan 14, 2016 at 22:22 UTC

    The point to map is that you can run the elements of the list through any code you like in the map block.

    map assigns the result of the last evaluated statement in the block, you don't always have to can't say return $foo;, but can just say $foo, as shown in all these examples. I tend to eschew many of Perl's shortcuts (like omitting a return statement from a block) because I prefer readability, but when it's a single statement, as is often the case with map, it's nice to be able to skip it.

    But if it's clearer to you to write:

    my @hash_names = map{ return {name => $_}; } @all_names;
    then by all means do that.

    edit: no, don't do that
    The way forward always starts with a minimal test.
      Using return in a map returns from the enclosing subroutine. Cf:
      say for sub { map { "\U$_" } @_ } ->(qw( abc def ghi )); # ABC # DEF # GHI

      versus

      say for sub { map { return "\U$_" } @_ } ->(qw( abc def ghi )); # ABC

      and even

      say for map { return "\U$_" } qw( abc def ghi ); # Can't return outside a subroutine at -e line 1. # [255]
      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,