http://qs1969.pair.com?node_id=11151293

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

are prone to inconsistencies.

Thoughts???

Cheers Rolf
(addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: Diving Data without autovivification
by Anonymous Monk on Mar 30, 2023 at 05:06 UTC
    Hi

    Looking at the SO page, the OP did say

    "it is the result of parsing JSON created by some other code that I have no control over. "

    I was wondering whether he is over thinking it, and just using a JSON Perl module to search the original data file would be better, less fragile?