I'm asking for advice on style, rather than how to solve a problem. How a professional would do it? What's readable to others -- and myself, in a year? So, all answers are maybe just opinion based and are welcome :-).

There's usual complex data structure AoHoAH... , not very deep. We can assume root is

$root = { value => [ ... ]};

Two types of array elements are "interesting":

{ type => 'items', value => [ ... ]} # and other key-value pairs { type => 'foo', value => { ... }} # and other key-value pairs

"Items" hash "points to" another array and is to be processed recursively. "Foo" hash is to be checked and may be replaced (split) with several hashes. Other "uninteresting" elements can be anything (but always hashrefs) and are to be left "as is".

The next sub is to be called as foobar( $root ), and hopefully will do everything right:

sub foobar { my $href = shift; $href-> { value } = [ map { foobar( $_ ) if $_-> { type } eq 'items'; $_-> { type } eq 'foo' ? SPLIT_FOO( $_ ) : $_ } @{ $href-> { value }}]; }

Or even shorter, moving a check out of sight:

sub foobaz { my $href = shift; $href-> { value } = [ map { foobar( $_ ) if $_-> { type } eq 'items'; SPLIT_IF_FOO( $_ ) } @{ $href-> { value }}]; }

The next sub has slightly less "punctuation noise" and skips assignment, and is to be called fooqux( $root-> { value }), i.e. now arrayref can serve as "root" instead of structure above.

sub fooqux { $aref = shift; splice @$aref, 0, @$aref, map { fooqux( $_-> { value }) if $_-> { type } eq 'items'; SPLIT_IF_FOO( $_ ) } @$aref }

What I'm not sure about all these, is they always rebuild any array within original structure, even if there's no "foo" elements at all. With condition checking moved to SPLIT, the SPLIT_IF_FOO is always called for all elements, regardless. Next sub prevents these shortcomings, but uses Perl's "no-no" -- the C-style loop.

sub fooquux { $aref = shift; for ( my $i = 0; $i < @$aref; $i ++ ) { my $item = $aref-> [ $i ]; fooquux( $item-> { value }) if $item-> { type } eq 'items'; next unless $item-> { type } eq 'foo'; my @list = SPLIT_FOO( $item ); splice @$aref, $i, 1, @list; $i += $#list } }

And, not sure what's worse, to splice potentially many times or to always replace with new array. Or maybe there's "best" idiomatic way to solve such problem?


In reply to To splice or not to splice? What implementation is more readable, efficient, etc.? by vr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.