Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Re: Fold a list using map splices

by Aristotle (Chancellor)
on Feb 19, 2003 at 22:59 UTC ( #236871=note: print w/replies, xml ) Need Help??

in reply to Fold a list using map splices

Iterating your splicing map over the same array its block modifies as a side effect is a really dirty approach though; no wonder you have to test $_ to guard against its failures. The right way to do this is in two steps:
my @spliced; push @spliced, [ splice @_, 0, $num_elements ] while @_; my @result = map func1($_), @spliced;
or maybe the straightforward
my @result; push @result, func1([ splice @_, 0, $num_elements ]) while @_;
It's awkward in Perl 5, that's true. Perl 6 is going to do away with this limitation of the list iteration functions and operators.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re: Fold a list using map splices
by hiseldl (Priest) on Feb 20, 2003 at 15:25 UTC

    I like the straightforward,

    push @result, func1([ splice @_, 0, $num_elements ]) while @_;
    but this expression could not be placed in a sub's parameter list because push does not return a list, rather it returns the number of new elements in the list.

    To clarify, this technique is used primarily to transform function parameters before they get passed. I could not use your two step method for that case. This technique is useful for creating HTML tables with N columns, where Tr() and td() both accept array refs. And, in order to fold the list without breaking stride, I used map.

    As a side note, I have been programming in Lisp for the last couple months, so I'll admit that this technique appears more functional than procedural. :-)

    What time is it? It's Camel Time!

    P.S. A matter of opinion:
    two steps is right? Just because our styles are different does not make either one of them right or wrong. It's a bit strong to say that your code is right, because that implies that my code is wrong. Let's agree that it is *your opinion* that "two steps" is the right/better way or *you prefer* "two steps." As a highly respected individual in this community, you affect the perceived usefulness of every node on which you comment. And I, for one, don't want to believe that you are an arrogant person, so please update your node to reflect that it *is* your opinion rather than a matter of fact.

      I'm not saying that my approach is the sole possible correct one, but I do believe that yours is wrong. The way it turns out to work is more of an accidental feature than something you should rely on. If you really don't want to create a temporary array, I suggest you do something like
      map func1([ splice @_, 0, $num_elements ]), 0 .. (@_/$num_elements);
      Iterating the map over an array while modifying it at the same time is wrong.

      Makeshifts last the longest.

        Ok. After more experimentation, I understand your point. Basically the question you are asking me is "why should I iterate over the last part of the list that may not exist?"

        So, what I need to do is change the list at the end of the map, to a list that will be used to count the new elements, rather than counting all of the elements in the original list.

        While I still disagree with you about "right" and "wrong," you have made a valuable point which makes the map more efficient. Thank you.

        What time is it? It's Camel Time!

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://236871]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2022-06-27 06:16 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (86 votes). Check out past polls.