jjohhn has asked for the wisdom of the Perl Monks concerning the following question:

I looked through documentation of arrays and slice, but I could not find the answer...
How do I split a list into two things: the head (a scalar) and the rest of the list (a list)?

Replies are listed 'Best First'.
Re: head of list + rest of list
by Forsaken (Friar) on May 18, 2005 at 17:57 UTC
    Well, there's a couple of ways to do it:
    my($scalar, @restofarray) = @array;
    or, even simpler...
    my $scalar = shift(@array);
    and @array will contain the remainder.

    disclaimer: ignoring differences between arrays and lists for the sake of simplicity

    Remember rule one...

Re: head of list + rest of list
by Corion (Patriarch) on May 18, 2005 at 17:58 UTC

    Perl allows many ways, depending on whether you want Haskell-style list partition, or imperative list manipulation:

    # Haskell programmer: my ($head,@tail) = @list; # Shell programmer my ($head) = shift @list; my @tail = @list; # Perlfunc Author ($head) = splice @list, 0, 1; @tail = @list;

    Put $head in list context for the splice example

      You left out "C programmer":
      /\* how are we supposed to declare the size of variables again? */; my $head; /\* scalar (could be number OR string) */; my @tail; /\* array of scalars (could be numbers or strings, and grows + dynamically) */; $head = $list[0]; /\* why isn't this @list[0] ? */; for (my $i = 1; $i <= $#list; $i++) { $tail[$i - 1] = $list[$i]; }

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

      ...and Java Programmer:
      Package ArraySeperator; sub new { my ( $class, @rest ) = @_; my $self = [@rest]; bless $self, $class; return $self; } sub head { my $self = shift; return $self->[0]; } sub rest { my $self = shift; my $size = scalar @$self; return @$self->[ 1 .. $size ]; } Package main; my $head; my @rest; my $seperator = ArraySeperator->new( @list ); $head = $seperator->head(); @rest = $seperator->rest();
      Update:
      merlyn, that is not part of the joke. You just have too good of an eye, I guess! It's fixed now. Thanks!
        s/Package/package/ :)

      shift and splice don't work on lists.

      These only work on arrays:

      # Haskell programmer: my ($head, @tail) = @array; # Shell programmer my $head = shift @array; my @tail = @array; # Perlfunc Author my $head = splice @array, 0, 1; my @tail = @array;

      These work on lists (including arrays):

      # Haskell programmer: my ($head, @tail) = list; # Shell programmer my @tail = list; my $head = shift @tail; # Perlfunc Author my @tail = list; my $head = splice @tail, 0, 1;

      By the way, there's no need to put $head in list context for this splice.

Re: head of list + rest of list
by brian_d_foy (Abbot) on May 18, 2005 at 18:43 UTC

    Are you sure you don't want to use Lisp? :)

    Frank Antonsen had an article about this is The Perl Review 1.1 when he talked about "Functional Programming in Perl".

    Besides getting the head and tail of a list, you also have to decide if you want the original array to stay intact.

    Non-destructive

    You can keep the original array as it is with a bit of copying.

    my( $head, @tail ) = @array;

    Destructive

    my $head = shift @array; my @tail = @array
    --
    brian d foy <brian@stonehenge.com>
Re: head of list + rest of list
by Transient (Hermit) on May 18, 2005 at 17:59 UTC
    #!/usr/bin/perl -w my @list = qw( 1 2 3 4 5 ); my @head = $list[0]; my @tail = @list[1..$#list]; print "List: $_\n" foreach @list; print "Head: $_\n" foreach @head; print "Tail: $_\n" foreach @tail; __END__ List: 1 List: 2 List: 3 List: 4 List: 5 Head: 1 Tail: 2 Tail: 3 Tail: 4 Tail: 5