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

my question is on the SPLICE function... it seems to be very strong but i can not get it right :(...I am using various syntax and scenarios but I can not phathom what splicing might return back to me... can anyone make it easier with regard to using the following syntaxes:
01 splice ARRAY, OFFSET, LENGTH, LIST 02 splice ARRAY, OFFSET, LENGTH 03 splice ARRAY, OFFSET
the first one replaces a length in the array with a provided list, the second one cutts for the specified length and all that I understand it pretty much, but I want to be able to set the OFFSET value right, I don't know if it is zero based like array indices are or if it is one-based :( thanks

Replies are listed 'Best First'.
Re: array manipulation
by toolic (Bishop) on Jun 15, 2009 at 16:32 UTC
Re: array manipulation
by jwkrahn (Abbot) on Jun 15, 2009 at 16:21 UTC

    splice returns the array elements that were removed from the original array.   All offsets in Perl are zero based.

      But that can change
      @a = 0..10; $[ = 2; warn $a[2]; warn splice(@a, 2, 1, 6); warn @a; __END__ 0 at - line 3. 0 at - line 4. 612345678910 at - line 5.
        Just a small note about your suggestion.

        I think changing $[ is very dangerous thing to do since the it is almost always 0. So if you need to change it for some reason make sure the change is local to the smallest scope needed.

        Thanks!

        I have spent too much time debugging my program on one occation when a module changed this globally ...

        si_lence

Re: array manipulation
by McDarren (Abbot) on Jun 15, 2009 at 16:20 UTC
    "I don't know if it is zero based like array indices are or if it is one-based"

    Why don't you just try it and see?

    my @foo = qw/1 2 3 4 5 6/; print "Index 1 is $foo[1]\n";
    Do that, and it should be obvious :)

    Update: duh, that was a really poor example, given that your question is about splice. Here is a better example:

    my @foo = qw/1 2 3 4 5 6/; my @bar = splice @foo, 1,2; print "Indexes 1 & 2 are @bar\n";
      I think biohisham means the index used in the offset for the splice function. But similarly,
      perl -le 'my @arr = qw/1 2 3/; print "Removing ",splice(@arr,1,1), "\n +"; print join(" - ", @arr), "\n"'
      Does show you that it is indeed 0-based (by default).
Re: array manipulation
by Gyatso (Novice) on Jun 15, 2009 at 17:50 UTC
    Hi biohisham, With the splice operator, you can add items to the middle of an array or remove them, letting the array grow or shrink as needed. The portion that is removed starts at the OFFSET element of the array and continues for LENGTH elements. If the LENGTH is not specified, it will cut to the end of the array. @LIST = splice(@ARRAY, OFFSET, LENGTH, @REPLACE_WITH); Eg: Cuttinmg out some elements of one array into another @myNames = ('Jacob', 'Michael', 'Joshua', 'Matthew', 'Ethan', 'Andrew'); @someNames = splice(@myNames, 1, 3); Think of the @myNames array as a row of numbered boxes, going from left to right, numbered starting with a zero. The splice() function would cut a chunk out of the @myNames array starting with the element in the #1 position (in this case, Michael) and ending 3 elements later at Matthew. The value of @someNames then becomes ('Michael', 'Joshua', 'Matthew'), and @myNames is shortened to ('Jacob', 'Ethan', 'Andrew'). Replacing some elements of an array with other elements: As an option, you can replace the portion removed with another array by passing it in the REPLACE_WITH argument. @myNames = ('Jacob', 'Michael', 'Joshua', 'Matthew', 'Ethan', 'Andrew'); @moreName = ('Daniel', 'William', 'Joseph'); @someNames = splice(@myNames, 1, 3, @moreName); In the above example, the splice() function would cut a chunk out of the @myNames array starting with the element in the #1 position (in this case, Michael and ending 3 elements later at Matthew. It then replaces those names with the contents of the @moreNames array. The value of @someNames then becomes ('Michael', 'Joshua', 'Matthew'), and @myNames is changed to ('Jacob', 'Daniel', 'William', 'Joseph', 'Ethan', 'Andrew'). Gyatso
      AHA, that means this replacement is actually mutual, the second array, @someNames gives to @myNames 3 elements and takes from @myNames 3 elements or whatever the size is for that matter. the offset is zero based.... and a combination of OFFSET, LENGTH, REPLACEMENT_ARRAY(or LIST) is so powerful Thanks Gyatso
        oops...no, I meant the other way around, this replacement is not mutual,.. that is what I meant to say.. since we have three arrays involved in there