Perl >> Command Splice()

by Lizhe.Xu » Tue, 05 Jun 2007 21:38:51 GMT

Hi All,
=20
The example given for splice function in the perldoc shows
sub aeq {
...
my(@a)=3D splice (@_, 0, shift);
...
}
I am confused about what the splice command does with the shift command =
and what the result of the command. Thanks.




Lizhe



Perl >> Command Splice()

by kratzers » Tue, 05 Jun 2007 22:09:19 GMT





Look at how aeq is called. The lengths of the arrays are passed before the
arrays. If the lengths are correct, the lengths are what the calls to shift
should return. Using these lengths and an offset of 0 should ensure that
splice removes all elements of the arrays following the length arguments.
So, "my(@a) = splice(@_,0,shift);" assigns to @a the values from the first
array in the call to aeq and "my(@b) = splice(@_,0,shift);" assigns to @b the
values from the second array in the call to aeq. Then, the lengths of the two
arrays are compared, and finally, all their elements are compared.



Perl >> RE: Command Splice()

by Lizhe.Xu » Tue, 05 Jun 2007 22:19:09 GMT

Thank you very much.

Lizhe

________________________________

From: Stephen Kratzer [mailto: XXXX@XXXXX.COM ]
Sent: Tue 6/5/2007 10:09 AM
To: XXXX@XXXXX.COM
Cc: Xu, Lizhe
Subject: Re: Command Splice()





Look at how aeq is called. The lengths of the arrays are passed before the
arrays. If the lengths are correct, the lengths are what the calls to shift
should return. Using these lengths and an offset of 0 should ensure that
splice removes all elements of the arrays following the length arguments.
So, "my(@a) = splice(@_,0,shift);" assigns to @a the values from the first
array in the call to aeq and "my(@b) = splice(@_,0,shift);" assigns to @b the
values from the second array in the call to aeq. Then, the lengths of the two
arrays are compared, and finally, all their elements are compared.




Command Splice()

by mumia.w.18.spam+nospam » Wed, 06 Jun 2007 01:42:47 GMT




Hello Lizhe. When you want information about a Perl function, you can
get it using the "perldoc" utility, like so:

Start->Run->"perldoc -f splice"

Start->Run->"perldoc -f shift"

To get an overview of the information available through perldoc, do this:

Start->Run->"perldoc perl"

I hope this helps you in the future.




Command Splice()

by mritty » Wed, 06 Jun 2007 03:10:15 GMT

On Jun 5, 1:42 pm, mumia.w.18.spam+ XXXX@XXXXX.COM (Mumia W.)




Or, if you'd prefer the manpage not disappear as you're reading the
last page...
Start->Run->cmd
then type 'perldoc -f splice' into the black box.

Or, presuming you have the Activestate distrobution,
Start->All Programs->ActivePerl->Documentation
and just click on perlfunc on the left side frame.

Paul Lalli



Similar Threads

1. Perl style splice functions for VB.NET and VBA

I have been frustrated for a while by the difficulty of manipulating
arrays in VBA and VB.NET -- in particular the awkwardness involved
in appending, prepending, or inserting new elements -- so to make
my life easier I wrote two functions that act something like Perl's
splice function.  I wrote the VBA version first, and then a slightly
different version for VB.NET.  Both versions are included here,
and they are both a little different from the Perl function, but
close enough that you should be able to make them functionally
identical without too much trouble if you happen to feel like it.

What the functions do is chop zero or more elements out of an input
array (which can be of any type) at a specified location, and then
splice zero or more new elements into the array at the same location,
all in a single function call.  Note that in the VB.NET version
the input array isn't changed, while in the VBA version (like in the
Perl function) it is.  (Note also that VB.NET version is the simpler
of the two, since I didn't have to worry about arrays having
something other than zero as a lower bound).

Here are some sample calls (VB.NET version):

	Dim qqq() as String = {"aaa", "bbb", "ccc"} 'Input array for the examples.

	ArraySplice(qqq, 0, 0, "xxx") '= {"xxx", "aaa", "bbb", "ccc"}
	ArraySplice(qqq, -1, 0, "xxx") '= {"aaa", "bbb", "ccc", "xxx"}
	ArraySplice(qqq, 1, 1) '= {"aaa", "ccc"}
	ArraySplice(qqq, 1, 1, "xxx", "yyy") '= {"aaa", "xxx", "yyy", "ccc"}
	ArraySplice(qqq, 5, 0, "xxx", "yyy") '= {"aaa", "bbb", "ccc", "", "", "xxx", "yyy"}

I'm sure others have done the same thing I've done here, but I
haven't come across any examples so far, so I'm posting this in
the hope that: 1) someone else might find these functions useful;
and 2) if there are any bugs in my code or mistakes in my approach
someone will notice and let me know.  Thanks in advance for any
comments!

One thing in particular: I needed to use generics for the VB.NET
version of the function (.NET Framework 2.0, actually), and this
was new to me, so I especially want to make sure this works properly
for everyone, no matter what framework version they are using or
how they have their environment configured.  I was a little surprised
that function calls could omit the "Of" clause, even though it is
part of the function definition!  This certainly makes using the
function simpler, but it's it's not clear to me why this is OK, so
it would be be very reassuring if someone could point me to a piece
of documentation that officially says this is allowed.


====== Start of VB.NET version of ArraySplice =====


'A VB splice function inspired by the one in Perl, although with a couple of differences.
'A copy is made of "arrayIn", "length" elements beginning at index "offset" are removed and replaced 
'with the contents of "list", and then the copy is returned.  The original input array is not modified.
'If "offset" is negative then nothing is removed, and new elements are appended to the end of the array.
'(Note: there is no need to explicitly supply the "Of" clause when calling this function).
Public Function ArraySplice(Of T)( _
    ByVal arrayIn As T(), _
    ByVal offset As Integer, _
    ByVal length As Integer, _
    ByVal ParamArray list As Object()) As T()

    arrayIn = arrayIn.Clone 'To protect the input array -- if you want arrayIn to be ByRef then remove.

    '=== Test and adjust arguments.

    If offset < 0 Then
        offset = arrayIn.Length 'A negative offset means append to end.
    ElseIf offset > arrayIn.Length Then
        ReDim Preserve arrayIn(offset - 1) 'A large offset will extend the array.
    End If

    If length < 0 Then
        Throw New ArgumentOutOfRangeException("length", "Value cannot be less than 0")
    ElseIf length > arrayIn.Length - offset Then
        length = arrayIn.Length - offset 'Can't remove more elements than you've got!
    End If

    '=== Now do the actual splicing.

    If list.Length > length Then 'arrayIn has to get bigger.
        Dim saveUBound As Integer = UBound(arrayIn)
        ReDim Preserve arrayIn(UBound(arrayIn) + list.Length - length)

        For i As Integer = saveUBound To offset + length Step -1
            arrayIn(i + list.Length - length) = arrayIn(i)
        Next
    ElseIf list.Length < length Then 'arrayIn has to get smaller.
        For i As Integer = offset + length To UBound(arrayIn)
            arrayIn(i + list.Length - length) = arrayIn(i)
        Next

        ReDim Preserve arrayIn(UBound(arrayIn) + list.Length - length)
    End If

    'Copy new values to arrayIn.
    For i As Integer = 0 To UBound(list)
        arrayIn(offset + i) = list(i)
    Next

    ArraySplice = arrayIn
End Function


====== Start of VBA version of ArraySplice =====


'This is a Perl style Splice function (for dynamic arrays only!).  It works by doing a ReDim on the input array and appropriately copying array elements.
'It differs from Perl in returning the altered input array, not the spliced elements, and in that a negative offset just means append to end, not count backwards from end.
'(Note that because the input array is altered by ReDim, but never replaced, LBound(arrayIn) remains unchanged).
Public Function ArraySplice(arrayIn As Variant, Optional ByVal offset As Integer = 0, Optional ByVal length As Integer = 0, Optional list As Variant) As Variant
    If IsMissing(list) Then list = Array()

    '=== First test, and possibly adjust, the input arguments.

    If Not IsArray(arrayIn) Then Err.Raise 5
    If Not IsArray(list) Then Err.Raise 5

    If offset < 0 Then
        offset = UBound(arrayIn) + 1 - LBound(arrayIn)
    ElseIf offset > UBound(arrayIn) + 1 - LBound(arrayIn) Then
        ReDim Preserve arrayIn(LBound(arrayIn) To LBound(arrayIn) + offset - 1)
    End If

    If length < 0 Then
        Err.Raise 5 '(It would actually make sense to allow negative values for length, but it would just be too much trouble to implement for too little value).
    ElseIf length > UBound(arrayIn) + 1 - (LBound(arrayIn) + offset) Then
        length = UBound(arrayIn) + 1 - (LBound(arrayIn) + offset) 'Can't remove more than you've got, so adjust the value of length,
    End If

    Dim arrayInLen As Integer, listLen As Integer, i As Integer
    arrayInLen = UBound(arrayIn) + 1 - LBound(arrayIn)
    listLen = UBound(list) + 1 - LBound(list)

    'If the output should be a zero length array then throw an error, because there is no reliable way to make this happen in VBA.
    '(You can't use ReDim to create a zero length array, and you can't even always set arrayIn = Array()).
    If UBound(arrayIn) + listLen - length < LBound(arrayIn) Then Err.Raise 5

    '=== Now we can do the actual splicing.

    'Expand or reduce the size of the array, and shift the elements not being removed appropriately.
    If listLen > length Then
        Dim originalUBound As Integer
        originalUBound = UBound(arrayIn)

        ReDim Preserve arrayIn(LBound(arrayIn) To UBound(arrayIn) + listLen - length)

        For i = originalUBound To LBound(arrayIn) + offset + length Step -1
            arrayIn(i + listLen - length) = arrayIn(i)
        Next
    ElseIf listLen < length Then
        For i = LBound(arrayIn) + offset + length To UBound(arrayIn)
            arrayIn(i + listLen - length) = arrayIn(i)
        Next

        ReDim Preserve arrayIn(LBound(arrayIn) To UBound(arrayIn) + listLen - length)
    End If

    For i = LBound(list) To UBound(list)
        arrayIn(LBound(arrayIn) + offset + i - LBound(list)) = list(i)
    Next

    ArraySplice = arrayIn
End Function


====== End of ArraySplice versions =====
-- 
John Brock
 XXXX@XXXXX.COM 

2. Trying to splice.... - Perl

3. splicing an array

Hi all,

I've an array of about 300 elements. I want to splice 7 elements at the
time, process this and then splece another 7 elemnts untill the end:

first ploblem if I use the scann_array function, perl say:

main::scann_array() called too early to check prototype at
G:\addresse\scrape.pl line 36.

and I don't know what that mean.

Ok I changed this an call splice in the while loop,

my ($name,$rub,$nl,$addr,$map,$tet,$capital) = splice(@a, 0,6);

but then perl says:

Use of uninitialized value in concatenation (.) or string at
G:\addresse\scrape.pl line 37, <FILE> line 106.
106 is the last line of the file, and this error appear at the end of
the execution, many times, but also in the middle of the output

Thanks.
Xbiton

----------------------------------
my @file = glob("*.eu");

foreach my $f (@file){
    open(FILE, "$f");
        my @a =();
            @a =<FILE>;
            my $count =@a;

           while(@a){
            my ($name,$rub,$nl,$addr,$map,$tet,$capital) =
scann_array(@a);
            print "$name,$rub,$nl,$addr,$map,$tet,$capital";
        }

             
}

sub scann_array(\@){
    return splice(@{$_[0]},0,6);
}

4. Complicated Use of Splice - Perl

5. Dynamic Splice

	I have the following line of code:

        $MyPrtLine = join( ",", (split (/ *\t */, $_))[9,10,11,15,25,28,31,32,34] );

	Is there a way to build splice portion: [9,10,11,15,25,28,31,32,34] so I could place as a variable either like:

	$MyPrtLine = join( ",", (split (/ *\t */, $_))[${MySplic}] );     
	or
	$MyPrtLine = join( ",", (split (/ *\t */, $_))${MySplice} );

	Both generate errors and what I am after is the ability to make an external value which I have as part of an ini file which I read in. I then generate the splice and no code changes.

	I am taking a large line ( 50+ fields ) and cutting down to what another user actually needs.

	Any way to accomplish?

      Thanks.


Wags ;)

	ps here is code that works with the first line(ie static splice). You should be able to cut and paste unless your mailer changes tabs to spaces. I ran it and it worked on xp, as 810 - 5.8.4.


#!perl

use strict;
use warnings;

while ( <DATA> ) {
    chomp;
    printf "%s\n",
                                join( ",", (split (/ *\t */, $_))[9,10,11,15,25,28,31,32,34] );
 }
 
__DATA__
VPkr	dx  	 6694	    	V	3	E	o	vHbUNJq      	      	-75581.96	jZJy	Z	13421216	sNvpbcSzF SVkecw djNTwqWj     	161123155 	H6	r	                              	    	79416787	ULR ebJnUiTnYgP               	        	                              	31638847	vbusYccDz FPEsDy srjiHhzs     	fcP 	        	*MQ FskP	cytKrr KAy soVdG              	    	          	        	          	6752-17-39	AFn 	    	 	eZ	yvgu	+78789	 381595527
vnfi	FC  	 7617	3455	Q	5	C	P	pVQSdHYUuN   	      	+97317.36	cUds	f	94779484	HIZXT tAGRyJwiZokJfo          	779586649 	X6	M	                              	    	59613139	vWuQf fjykoJF                 	        	                              	57762176	IwjeG CSMeynturIUEzk          	BvJ 	        	*oi gCtr	GxqzZg REI ZILUr              	    	          	        	          	1916-88-42	Rwo 	    	 	TA	jhWg	+47967	 793474171
Tnkp	ZE  	 4697	    	r	4	j	y	IKGbYuA      	      	+28363.78	BhfJ	s	39813118	CMEBGxJuZ ExCUxUn- krzx MfsbDp	616926757 	u8	f	                              	    	59891125	nGFe iVWItm vBXF DtbnH        	        	                              	51759434	WuzSdMPRk zkjFKrZ- sgeH WuQGnE	epp 	        	*em oXVU	cNCJfh seu xbIxH              	    	          	        	          	6374-73-93	Tzm 	    	 	VZ	DbBk	+83234	 666885577



*******************************************************
This message contains information that is confidential
and proprietary to FedEx Freight or its affiliates.
It is intended only for the recipient named and for
the express purpose(s) described therein.
Any other use is prohibited.
*******************************************************

6. popping, shifting or splicing an array??? - Perl

7. Using $# in a splice with split

Hi Perl buddies,

  Can I do something like this:

 my $line = 'One Two Three Four Five Six';
 my( $first, $last ) = (split(' ', $line))[0,$#(split(' ', $line))];

This does not work.  What I want to do is to find the index of the last
element of a list created by split, and use it in a slice on the same
line.  Wow, that sounds garbled when I re-read it.  With the above
example, I want the two variables to contain the following:

  $first = 'One';
  $last = 'Six';

I realize I can do this in two steps:

  my $line = 'One Two Three Four Five Six';
  my @line = split(' ', $line);
  my($first, $last) = @line[0,$#line];

But I was wondering if it can be done on one line.

--Errin

PS  ----  oops ... I just remembered negative indexing.  This works:

  my $line = 'One Two Three Four Five Six';
  my( $first, $last ) = (split(' ', $line )[0, -1];

Weeeeeeeeeeeeeeeee!

8. Web data clean up - Tie::File splice question(s) - Perl