I was involved in a
SO discussion, where the OP wanted to find the emails from certain users, but from a problematic data structure
[
{
foo => {
browser => "firefox",
contact => [{ email => "foo\@example.org" }, { phone =
+> 2125551212 }],
lang => "en",
},
},
{
bar => {
browser => "lynx",
contact => [{ email => "bar\@example.com" }, { phone =
+> 9125551212 }],
lang => "fr",
},
},
];
One of the problems is to avoid autovivification.
The usual answers imply
but - to my surprise - none of them is core.
after some meditation I came up with the following solution.
It looks so idiomatic and generic to me that I'm asking myself if I missed something:
use v5.12.0;
use warnings;
use Test::More;
use Data::Dump;
sub orig_data {
return
[
{
foo => {
browser => "firefox",
contact => [{ email => "foo\@example.org" }, { phone =
+> 2125551212 }],
lang => "en",
},
},
{
bar => {
browser => "lynx",
contact => [{ email => "bar\@example.com" }, { phone =
+> 9125551212 }],
lang => "fr",
},
},
];
}
my $data = orig_data();
my @emails;
# ------ short version
@emails =
map { $_->{email} // () }
map { @{ $_->{contact} // [] } }
map { $_->{bar} // () }
@$data;
is_deeply(\@emails, ["bar\@example.com"], "result ok");
is_deeply($data, orig_data(), "no autovivification");
# ------ long symmetrical version
@emails =
map { $_->{email} // () }
map { @$_ }
map { $_->{contact} // () }
my @users = # only necessary to check uni
+queness
map { $_->{bar} // () }
map { @$_ }
$data;
is_deeply(\@emails, ["bar\@example.com"], "result ok");
is_deeply($data, orig_data(), "no autovivification");
# --------- this would vivify new elements
# map { $_->{bar}{contact} // () }
# map { @$_ }
# $data;
# is_deeply($data, orig_data ,"no autovivification");
done_testing;
OUTPUT:
ok 1 - result ok
ok 2 - no autovivification
ok 3 - result ok
ok 4 - no autovivification
1..4
NB: as an extra benefit I can check if @emails and @users have only one element to catch glitches in the data. Those arrays of one element hashes like
- [{ email => "bar\@example.com" }, { phone => 9125551212 }],
are prone to inconsistencies.
Thoughts???
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.