How do I convert an array or a list into a hashref?

468 Views Asked by At

I have a list like this:

my $myV3VersionOfData = ["ZG","ZB","CXLDN",...];

and I want to convert it into a dictionary like this:

my $entries = {
'ZG' => {
'value' => 'ZG'
},
'ZB' => {
'value' => 'ZB'
},
'CXLDN' => {
'value' => 'CXLDN'
},
...
};

I tried this so far, but it doesn't work and gives me an error:

Can't use string ("ZG") as a HASH ref while "strict refs" in use at..

I understand this is occurring since I'm trying to assign the key value from the list, but how do I convert this list into a dictionary shown above?

my %genericHash;
for my $entry (@$myV3VersionOfData) {
  $genericHash{ $entry->{key} } = $entry->{value};
}

How can I achieve this? I am new to Perl, and I have tried a bunch of things but it doesn't seem to work. Can anyone please help with this?

5

There are 5 best solutions below

0
On BEST ANSWER

Here's how I've done it for over 10 years.

#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper qw(Dumper);

my %entries;
my @myV3VersionOfData = ("ZG","ZB","CXLDN");
foreach (@myV3VersionOfData) {
    $entries{$_}{'value'} = $_;
}

print Dumper \%entries;
0
On

Please study following code snippet for compliance with your problem.

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $myV3VersionOfData = ['ZG','ZB','CXLDN'];
my $hashref;

$hashref->{$_}{value} = $_ for @$myV3VersionOfData;

say Dumper($hashref);

Output

$VAR1 = {
          'CXLDN' => {
                       'value' => 'CXLDN'
                     },
          'ZB' => {
                    'value' => 'ZB'
                  },
          'ZG' => {
                    'value' => 'ZG'
                  }
        };
1
On

You were close. Here is one way to create a hash reference from an array reference:

use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys=1;

my $myV3VersionOfData = ["ZG","ZB","CXLDN"];
my $entries;
for (@{ $myV3VersionOfData }) {
    $entries->{$_} = {value => $_};
}

print Dumper($entries);

Output:

$VAR1 = {
          'CXLDN' => {
                       'value' => 'CXLDN'
                     },
          'ZB' => {
                    'value' => 'ZB'
                  },
          'ZG' => {
                    'value' => 'ZG'
                  }
        };
1
On

If you want to go through every element, to compute a new element, then you can use the map function. As map, can return multiple values, you return two values for each entry. And those can be converted to a hash.

my $array   = ["ZG","ZB","CXLDN"];
my %hash    = map { $_ => { value => $_ } } @$array;
my $hashref = { map { $_ => { value => $_ } } @$array };
0
On

We want

'ZG' => { 'value' => 'ZG' }      # Copied literally from the Question

But the ZG part is variable, so we use

$_ => { 'value' => $_ }

Now loop!

my %genericHash = map { $_ => { 'value' => $_ } } @$myV3VersionOfData;
my $entries = { map { $_ => { 'value' => $_ } } @$myV3VersionOfData };

It's not clear which one you want.

Of course, it could also be done using a foreach loop.

my %genericHash;
for (@$myV3VersionOfData) {
   $genericHash{$_} = { 'value' => $_ };
}