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

I want to unshift one scalar to the top of an array.

This is the only thing I can get past perl.

my @array = ( "Top" ); unshift (@array, @output);

Which seems wasteful, I have tried unsucessfully

unshift (("Top"), @output);

Is there a better way to do it without adding "my @array" to the mix?

Thanx

Replies are listed 'Best First'.
Re: unshift single scalar
by Not_a_Number (Prior) on Aug 09, 2014 at 18:37 UTC

    If I understand correctly, you want:

    unshift (@output, "Top");

    The array that you want to alter should be the first argument to unshift.

    Update: Added explanation.

      I saw that in the docs but it did not explain what it was, but it says this:

      Starting with Perl 5.14, unshift can take a scalar EXPR, which must hold a reference to an unblessed array. The argument will be dereferenced automatically. This aspect of unshift is considered highly experimental. The exact behaviour may change in a future version of Perl.

      But that is a winner, it works.

        No. When the docs say 'unshift can take a scalar EXPR', they mean as the first argument, eg:

        my $ref = [ 2, 3 ,4 ]; unshift $ref, 1;

        But that's probably too much information. What you need to understand is that the standard (non-experimental) syntax for unshift is:

        unshift ARRAY,LIST

        It so happens (as is often the case) that the LIST that you want to add at the beginning of your ARRAY consists of just one element (namely 'Top').

        Maybe the doc for unshift could benefit from a less obscure example of usage?

Re: unshift single scalar
by dsheroh (Monsignor) on Aug 10, 2014 at 07:35 UTC
    Basically, no, you can't use a constant as the first argument to unshift because unshift modifies its first argument and you can only modify variables. unshift (("Top"), @output) fails for the same reason that 3 += 1 fails.

    However, despite your first example (with the "wasteful" @array variable), your English description of what you want to accomplish (putting 'Top' at the start of @output) sounds like you may just have your arguments to unshift in the wrong order. The first argument is the array to modify, the second is the list of items to prepend to the array, so you would use unshift @output, 'Top' even though the end result is to modify @output to contain ('Top', @output). (In your first example, while it is syntactically valid, the end result is that @output is unmodified and @array ends up with the contents (@output, 'Top'), not ('Top', @output).)

Re: unshift single scalar
by LanX (Saint) on Aug 09, 2014 at 18:15 UTC
    Are you looking for push ?

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: unshift single scalar
by Bodger (Acolyte) on Aug 09, 2014 at 18:42 UTC

    I do not want "push" that puts it at the bottom of the list. I want to put the single scalar value at the top of the list see example.

    # What list looks like before I unshift it 0 "Item 1" 1 "Item 2" After I do the unshift (or whatever command). 0 "Top" 1 "Item 1" 2 "Item 2"

    I just feel there has to be a more elegant way of doing this.

      The post by Not_a_Number (and other monks) already gave you the solution:
      unshift @output, "Top";
      Quite simple, isn't it?
      > I do not want "push" that puts it at the bottom of the list.

      That's the code you posted as demonstration of what you want

      DB<108> @array = ( "Top" ); => "Top" DB<109> @output=1..3 => (1, 2, 3) DB<110> unshift (@array, @output); => 4 DB<111> @array => (1, 2, 3, "Top")

      and that's what push does

      DB<112> push @output, "Top" => 4 DB<113> @output => (1, 2, 3, "Top")

      maybe you should check your examples before posting?

      Besides: I've never heard of "bottom" or "top" of lists or even arrays. "Start" and "End" are much better description for chains w/o any vertical orientation.

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

        Besides: I've never heard of "bottom" or "top" of lists or even arrays. "Start" and "End" are much better description for chains w/o any vertical orientation.

        It's not so uncommon when one is working with stacks: you push items onto the top of the stack, and pop them off the top again. Since this is where Perl's push and pop got their names from, the terminology is not malapropos, even if it is perhaps uncommon for general arrays and lists.

      Here are some examples that may help drive the point home:

      c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @output = qw(OldTop Second Third); dd \@output; ;; unshift @output, 'NewTop'; dd \@output; ;; my @otherarray = qw(uno dos tres); unshift @output, @otherarray; dd \@output; " ["OldTop", "Second", "Third"] ["NewTop", "OldTop", "Second", "Third"] ["uno", "dos", "tres", "NewTop", "OldTop", "Second", "Third"]

      ... a more elegant way ...

      I don't know if you will consider this more elegant or not:

      c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @output = qw(OldTop Second Third); dd \@output; ;; @output = ('NewTop', @output); dd \@output; " ["OldTop", "Second", "Third"] ["NewTop", "OldTop", "Second", "Third"]
      The disadvantage of this approach is that it requires the construction of a temporary list, which in the case of a large  @output array will be correspondingly large.