Pushing a list of values to a list of arrays, one per array.
This is useful for when you need to keep multiple arrays with data for a given object at the same offset (that is, element N of all the arrays contains information for the same object). While an array of hashes would probably be better, I offer this.
Note: the function name is to be pronounced like "mooolti-pooosh", like Leeloo in "The Fifth Element". Failure to do so might cause the future to cease to be.
sub multi_push { my $adj = @_/2; while (@_) { my $arg = splice(@_, $adj--, 1); push @{ +shift }, $arg; } } multi_push( (\@names, \@ages, \@locs) => split /::/, $record );

Replies are listed 'Best First'.
(tye)Re: multi-push
by tye (Sage) on Feb 14, 2001 at 22:34 UTC

    I'm getting more and more used to having mapcar:

    mapcar { push @{shift @_}, @_ } [\@user,\@pw,\@uid,\@gid], map { [ split /:/, $_ ] } <PASSWD>; # Or, if you don't have mapcar prototyped at compile time: mapcar( sub { push @{shift @_}, @_ }, [\@user,\@pw,\@uid,\@gid], map { [ split /:/, $_ ] } <PASSWD> );
            - tye (but my friends call me "Tye")
multi-push-super (Re: multi-push)
by gryng (Hermit) on Feb 14, 2001 at 21:58 UTC
    japhy, very neat little code.

    Am I allowed to make some suggestions though? I am concerned mainly with what would happen if $record contained a different amount of fields than you specify. If so, then the program will attempt to either use one of the record's values as an array reference (ouch!), or stick a reference of one of your arrays in another (ewww :) ).

    So perhaps a little change to your arguments:

    multi_push( \(@names, @ages, \@locs) => [split /::/, $record] );

    The first line hasn't changed, we still get 3 references to an array -- \(@a, @b) is shorthand for (\@a, \@b). The second line is only changed in that the array of values is turned into a reference to an array of values.

    So how about a rewrite of the code to use the new parameter syntax:

    sub multi_push{ my @v = @{ pop @_ }; my @fs = @_; for my $f (@fs) { push @{ $f }, +shift @v; } }
    Or if you like something closer to your code:
    sub multi_push { my @v = @{ pop @_ }; while(@_) { push @{ +shift }, +shift @v; } }

    Warnings: Not tested, as I don't have the luxury of perl access at work :( :( . (So maybe there are more +'s than necessary :) ).

    Welp, have fun.

    Ciao,
    Gryn

      Nice addition to my code. I was thinking the same thing, but I decided not to act upon it. I felt lazy. ;)

      japhy -- Perl and Regex Hacker
        Oh yeah, I also wanted to say I liked the pronuciation guide! mooolti-pass!

        Ciao,
        Gryn