http://www.perlmonks.org?node_id=237632


in reply to Re: Fold a list using map splices
in thread Fold a list using map splices

The index variables there kept tickling me as not right. This is Perl, not C, there has to be a way to do this without explicit indices and no copying. Guess what. :) It's actually simpler than I was expecting and definitely goes in my "cool snippets" file.
sub mapn (&@) { my ($cb, $n) = splice @_, 0, 2; splice @_, 0, 0, (undef)x$n; map{ splice @_, 0, $n; $cb->(@_[0 .. (@_ < $n ? $#_ : $n-1)]); } 0 .. (@_/$n)-1; } sub mapnz (&@) { my ($cb, $n) = splice @_, 0, 2; splice @_, 0, 0, (undef)x$n; map{ splice @_, 0, $n; $cb->(@_[0 .. $n-1]); } 0 .. (@_/$n)-1; }

BrowserUk++ for the inspiration!

Update: fixed mapnz

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^2: Fold a list using map splices
by BrowserUk (Patriarch) on Feb 22, 2003 at 06:31 UTC

    Nice twist++. Took me a while to work out why i doesn't destroy the input array. Not sure that I share your distaste for the index variable...'sides...mine's quicker:).

    You have a typo? ... an out-by-one error on your version of mapnz, it produces one too many rows. You either need to subtract 1 as you do in the mapn version or start your range from 1.


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.

      I was pretty sure yours would be quicker - but by how much is that?

      Thanks for the heads up on the one-off error..

      Makeshifts last the longest.

        You're both inspirational, guys++. However, it seems to me that you ought to put the padding at the end of the array; with the exception being that if the number of columns divides the length of the array with no remainder then you don't add the padding.

        Also I think that the splice on each iteration is wasteful, so I'll just change the indexes so that each row comes out correct.

        sub map_nbsp (&@) { my ($codeblock, $cols) = splice @_, 0, 2; splice @_, @_, 0, ('&nbsp;')x$cols if @_ % $cols; my $rows = int @_/$cols; map{ $codeblock->(@_[$cols*$_ .. $cols*($_+1)-1]); } 0 .. ($rows)-1; } my @tabular_data = map{ 1000+int rand 8999 } 1 .. 9; print table( {border=>1}, map_nbsp{ Tr( td( \@_ ) ); } 4, @tabular_data );

        About 15% on average. Hardly worth worrying about in the scheme of things.


        Examine what is said, not who speaks.
        1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
        2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
        3) Any sufficiently advanced technology is indistinguishable from magic.
        Arthur C. Clarke.