Author image Brent Royal-Gordon


List::Part - Partition one array into several


    use List::Part;
    ($good, $bad)=part { !/substring/ } @array; #store arrayrefs into $good and $bad
    (*good, *bad)=part { !/substring/ } @array; #store into @good and @bad


List::Part implements the part function, allowing one array to be "partitioned" into several based on the results of a code reference.


There are many applications in which the items of a list need to be categorized. For example, let's say you want to categorize lines in a log file:

    my($success, $failure)=part { /^ERR/ } <LOG>;

Or, suppose you have a list of employees, and you need to determine their fate:

    my($lay_off, $give_raise, $keep)=part {
          $_->is_talented  ? 0 
        : $_->is_executive ? 1 
        :                    2
    } @employees;

Actually, the second one is better suited to part's alternate form, parta:

    my($lay_off, $give_raise, $keep)=parta
        [ sub { $_->talented }, sub { $_->is_executive }, qr// ] => 

Or maybe you just want yet another way to write the traditional Perl signoff:

    perl -MList::Part -e"print map{@$_}part{$i++%5}split'','JAercunrlkso  ettPHr hea,'"

List::Part can help you do those sorts of things.



part takes a code reference and an array and returns a list of array references. The coderef should examine the value in either $_ or its argument list and return a (zero-based) index indicating which array the value should go into. Built-in Perl functions that emit booleans, such as regular-expression matches or file operators, are also suitable for this--but note that the second array is the one that receives true values, not the first. Returning undef will cause part to throw away the value, so that none of the arrays will receive it.

The function is prototyped (&@), which means that, like the built-in map and grep, you can pass it a bare block without using sub.

Tip: As mentioned before, this function returns a list of array references; if you want the results to be assigned to (global) arrays, then assign to typeglobs:

    (*a, *b, *c)=part { ... } @list;


parta is a wrapper around part which can reduce the amount of code under certain circumstances. Instead of taking a code reference, parta takes an array reference containing strings or certain types of references; the index of the first item an incoming value "matches" is the index of the list it ends up in. For example:

    ($a, $b, $c)=part [ qr/a/, qr/b/, qr/c/ ] => qw(a b c aa ab bc);
    # $a=[ qw(a aa ab) ], $b=[ qw(b bc) ], $c=[ qw(c) ]

The match rules are fairly sophistocated, and vary based on the type of item in the arrayref:

  • Strings (and other plain scalars) are compared using eq.

  • Array references match if any of their elements matches the value.

  • Hash references match if their associated value in the hash, i.e. $hashref->{$value}, is true.

  • Code references match if, when invoked on the item, they return true.

  • Regexen (such as those produced by qr//) match if the item matches them.

  • Other references are compared using eq.

parta carries the prototype ($@).

Tip: If you want the results to include a "rejects" array, add an empty regex (qr//) to the end of the arrayref.


part is exported by default; parta can be exported specifically.


There are no known bugs, and since the code for this module is fairly simple, I don't expect there will be many.

Bug reports and enhancement requests are welcome, but I'm far more likely to act on them if they're accompanied by a patch fixing/implementing them. Also, if you get this to work on older versions of Perl without changing any functionality, I will happily apply your patch. Send reports/requests to <>.


The Perl 6 design, which includes a more powerful version of part.


Brent Dax <>


Copyright (C) 2003 Brent Dax. All Rights Reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 169:

=back doesn't take any parameters, but you said =back 4