Concatenating arrays using references when defining a new data structure
First post for me :)
I'm not sure if this is possible, but I would like to know.
Given the following code ...
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %email_addresses = (
'fred' => [
'"Fred Blogs" <fred.blogs@domain.com>',
'"Fred Blogs" <fred.blogs@hotmail.com>'
],
'jane' => [
'"Jane Smith" <jane.smith@domain.com>',
'"Jane Smith" <jane.smith@hotmail.com>',
'"Jane Smith" <jane.smith@somwhere.com>'
],
'tom' => [
'"Tom Jones" <tom.jones@domain.com>'
]
);
my %recipients = (
'success' => [
$email_addresses{'fred'},
$email_addresses{'jane'}
],
'failure' => [
$email_addresses{'tom'}
]
);
print Data::Dumper->Dump([\%recipients], ['recipients']);
Output signal
$recipients = {
'success' => [
[
'"Fred Blogs" <fred.blogs@domain.com>',
'"Fred Blogs" <fred@hotmail.com>'
],
[
'"Jane Smith" <jane.smith@domain.com>',
'"Jane Smith" <jane.smith@hotmail.com>',
'"Jane Smith" <jane.smith@somwhere.com>'
]
],
'failure' => [
[
'"Tom Jones" <tom.jones@domain.com>'
]
]
};
As a result of both $recipients{'success'}
, and $recipients{'failure'}
are two-dimensional arrays, but this is not what I want. I would like them to be one dimensional arrays.
That is, for $recipients{'success'}
, I want Jane's email list to be added to Fred's email list, resulting in a single dimensional array containing 5 elements. Likewise, it $recipients{'failure'}
will be a one-dimensional array containing only one element.
So, I want it to look like this ...
$recipients = {
'success' => [
'"Fred Blogs" <fred.blogs@domain.com>',
'"Fred Blogs" <fred@hotmail.com>',
'"Jane Smith" <jane.smith@domain.com>',
'"Jane Smith" <jane.smith@hotmail.com>',
'"Jane Smith" <jane.smith@somwhere.com>'
],
'failure' => [
'"Tom Jones" <tom.jones@domain.com>'
]
};
Now here is the catch ... I want to know if this can be done at the point where I define my %recipients
- everything in one statement.
I know that I can achieve what I want programmatically after definition using additional instructions, but I am curious to see if it can be done all in one. I've tried various combinations of (), [], {} and dereferencing, but nothing worked.
Thanks everyone.
source to share
You essentially want to flatten the list of array references. Yes, it's easy to do.
I would advise you to just use a map and pass the list of keys you want to translate like this:
use strict;
use warnings;
use Data::Dumper;
my %email_addresses = (
'fred' => [
'"Fred Blogs" <fred.blogs@domain.com>',
'"Fred Blogs" <fred.blogs@hotmail.com>',
],
'jane' => [
'"Jane Smith" <jane.smith@domain.com>',
'"Jane Smith" <jane.smith@hotmail.com>',
'"Jane Smith" <jane.smith@somwhere.com>',
],
'tom' => [
'"Tom Jones" <tom.jones@domain.com>',
]
);
my %recipients = (
'success' => [map @{$email_addresses{$_}}, qw(fred jane)],
'failure' => [map @{$email_addresses{$_}}, qw(tom)],
);
print Data::Dumper->Dump([\%recipients], ['recipients']);
Outputs:
$recipients = {
'success' => [
'"Fred Blogs" <fred.blogs@domain.com>',
'"Fred Blogs" <fred.blogs@hotmail.com>',
'"Jane Smith" <jane.smith@domain.com>',
'"Jane Smith" <jane.smith@hotmail.com>',
'"Jane Smith" <jane.smith@somwhere.com>'
],
'failure' => [
'"Tom Jones" <tom.jones@domain.com>'
]
};
source to share