Array slice to end of array of indeterminate size

N

niall.macpherson

I have a string which I want to split into an array. I do not know how
many parts there are going to be , but I want everything except the
first 2 parts.

Here is what I have tried so far

------------------------------------------------------------------------------------------------------------------------------
use strict;
use warnings;
use Data::Dumper;

my $teststring = 'abc,def,ghi,jkl,mnop';

## Method 1 - OK but need to know how many elements
my @colnames = (split(/,/, $teststring))[2..4];
print Dumper \@colnames;

## Method 2 - OK but is there a more elegant way ?
(undef, undef, @colnames) = split(/,/, $teststring);
print Dumper \@colnames;

## Method 3 - Returns empty array
@colnames = (split(/,/, $teststring))[2..(-1)];
print Dumper \@colnames;

exit(0);
----------------------------------------------------------------------------------------------------------------------------

I was hoping I could use an array slice and use the range [2..-1] to
get from element 2 to the end (Method 3) but this gives me an empty
array.

Method 2 works but it led me to think that if I had a much bigger
string and I wanted from item 15 to the end I would have to do

(undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, @colnames) = split(/,/,
$teststring);

which is messy.

Can anyone advise the best way ?

Thanks
 
D

DJ Stunks

I have a string which I want to split into an array. I do not know how
many parts there are going to be , but I want everything except the
first 2 parts.

Here is what I have tried so far

------------------------------------------------------------------------------------------------------------------------------
use strict;
use warnings;
use Data::Dumper;

my $teststring = 'abc,def,ghi,jkl,mnop';

## Method 1 - OK but need to know how many elements
my @colnames = (split(/,/, $teststring))[2..4];
print Dumper \@colnames;

## Method 2 - OK but is there a more elegant way ?
(undef, undef, @colnames) = split(/,/, $teststring);
print Dumper \@colnames;

## Method 3 - Returns empty array
@colnames = (split(/,/, $teststring))[2..(-1)];
print Dumper \@colnames;

exit(0);
----------------------------------------------------------------------------------------------------------------------------

I was hoping I could use an array slice and use the range [2..-1] to
get from element 2 to the end (Method 3) but this gives me an empty
array.

Method 2 works but it led me to think that if I had a much bigger
string and I wanted from item 15 to the end I would have to do

(undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, @colnames) = split(/,/,
$teststring);

which is messy.

Can anyone advise the best way ?

Thanks

if you always want the same number of elements (ie: last 3) then just
use negative indexing in your slice:

my @slice = @original_array[ -3..-1 ];

if you always want from the 2nd element to the end of the array

my @slice = @original_array[ 2..$#original_array ];

-jp
 
B

Ben Morrow

Quoth (e-mail address removed):
I have a string which I want to split into an array. I do not know how
many parts there are going to be , but I want everything except the
first 2 parts.

Here is what I have tried so far

------------------------------------------------------------------------------------------------------------------------------
use strict;
use warnings;
use Data::Dumper;

my $teststring = 'abc,def,ghi,jkl,mnop';

## Method 1 - OK but need to know how many elements
my @colnames = (split(/,/, $teststring))[2..4];
print Dumper \@colnames;

## Method 2 - OK but is there a more elegant way ?
(undef, undef, @colnames) = split(/,/, $teststring);
print Dumper \@colnames;

## Method 3 - Returns empty array
@colnames = (split(/,/, $teststring))[2..(-1)];
print Dumper \@colnames;

exit(0);
----------------------------------------------------------------------------------------------------------------------------

I was hoping I could use an array slice and use the range [2..-1] to
get from element 2 to the end (Method 3) but this gives me an empty
array.

Method 2 works but it led me to think that if I had a much bigger
string and I wanted from item 15 to the end I would have to do

(undef, undef, undef, undef, undef, undef, undef, undef, undef, undef,
undef, undef, undef, undef, undef, @colnames) = split(/,/,
$teststring);

which is messy.

Can anyone advise the best way ?

my @colnames = split /,/, $teststring;
splice @colnames, 0, 2;

Ben
 
N

niall.macpherson

DJ Stunks wrote:

if you always want from the 2nd element to the end of the array

my @slice = @original_array[ 2..$#original_array ];

-jp

Yes - this is what I wanted , i.e from the 2nd element (or nth element
in the general case) to the end. I was aware of this method but I was
really wondering how I could do it without using an intermediate array

This works just fine
my @original_array = split(/,/, $teststring);
my @slice = @original_array[2..$#original_array];
print Dumper \@slice;

but I wanted if possible to do the assignment and the split in a single
line to make the code clearer.

If $teststring is very large I will end up making a copy each time and
since I never need the data in $teststring which comes before the third
comma this seems wasteful. It also introduces an extra variable which
does not help with readablilty.

original_array never needs to be used anywhere else in the code so I
would like to eliminate it if possible.
 
N

niall.macpherson

Just realised that this

@colnames = split(/,/, $teststring);
splice(@colnames, 0, 2);
print Dumper \@colnames;

is a bit better as it avoids using the temporary array but I would
still like to get it on a single line if possible.
 
D

Dr.Ruud

(e-mail address removed) schreef:
I have a string which I want to split into an array. I do not know how
many parts there are going to be , but I want everything except the
first 2 parts.


I think the "(undef, undef, @ary)" way is fine.

Just another variant:

#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;

my $str = 'abc,def,ghi,jkl,mnop' ;

# my (undef, undef, @colnames) = split ',', $str ;
my @colnames = do{ local @_=split',',$str; @_[2..$#_] } ;

print Data::Dumper->Dump( [\@colnames], [qw(*colnames)] ) ;
 
D

David Squire

Just realised that this

@colnames = split(/,/, $teststring);
splice(@colnames, 0, 2);
print Dumper \@colnames;

is a bit better as it avoids using the temporary array but I would
still like to get it on a single line if possible.

OK. Here it is on one line, just for fun, but I don't think it's
clearer, let alone more efficient :)

----

#!/usr/bin/perl
use strict;
use warnings;

my $data = '1, 2, 3, 4, 5, 6, 7, 8';
my @slice = (split /,\s*/, $data)[2..scalar(() = $data =~ m/,\s*/g)];
print join ', ', @slice;
 
X

xhoster

Just realised that this

@colnames = split(/,/, $teststring);
splice(@colnames, 0, 2);
print Dumper \@colnames;

is a bit better as it avoids using the temporary array

yes, that is the way I would do it too. Although I too wish
[2..-1] was extra magical to just do what I mean it to.
but I would
still like to get it on a single line if possible.

Sure it is.

my @colnames = split(/,/, $teststring); splice(@colnames, 0, 2);


Xho ;)
 
J

jdamon

Yes - this is what I wanted , i.e from the 2nd element (or nth element
in the general case) to the end. I was aware of this method but I was
really wondering how I could do it without using an intermediate array

If you don't mind using @_,

you can do the following...


#!/usr/bin/perl

use Data::Dumper;

my $teststring = 'abc,def,ghi,jkl,mnop,qrs,tuv,wx,yz';

split(",", $teststring) && print Dumper @_[2..$#_];
 
D

David Squire

Yes - this is what I wanted , i.e from the 2nd element (or nth element
in the general case) to the end. I was aware of this method but I was
really wondering how I could do it without using an intermediate array

If you don't mind using @_,

you can do the following...


#!/usr/bin/perl

use Data::Dumper;

my $teststring = 'abc,def,ghi,jkl,mnop,qrs,tuv,wx,yz';

split(",", $teststring) && print Dumper @_[2..$#_];

----

#!/usr/bin/perl
use strict;
use warnings;

my $teststring = 'abc,def,ghi,jkl,mnop,qrs,tuv,wx,yz';
split(",", $teststring) && print join ' ', @_[2..$#_];

----

Output:
Use of implicit split to @_ is deprecated at ./test.pl line 6.
ghi jkl mnop qrs tuv wx yz


DS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,573
Members
45,046
Latest member
Gavizuho

Latest Threads

Top