Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > question on reference to array slice

Reply
Thread Tools

question on reference to array slice

 
 
Rick
Guest
Posts: n/a
 
      07-29-2007
Hi, guys

In C we can store a set of pointers which point to different arrays
into an array of pointer. This way we could fast access different
array by looking it up in this pointer array. Is there anyway to do
this in Perl. I've been trying different things and no luck so far.

LIke:
@nums = (1 .. 20);

I want to store the reference to @nums[1..10] into $data[0], and the
reference to @nums[11:20] into $data[1], so that I could visit, for
example, the second set of @nums by something like $data[1][5] to get
15.

Is this possible for Perl anyway?

Any input is really appreciated!!

-PD

 
Reply With Quote
 
 
 
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      07-29-2007
Rick wrote:
> In C we can store a set of pointers which point to different arrays
> into an array of pointer. This way we could fast access different
> array by looking it up in this pointer array. Is there anyway to do
> this in Perl. I've been trying different things and no luck so far.
>
> LIke:
> @nums = (1 .. 20);
>
> I want to store the reference to @nums[1..10] into $data[0], and the
> reference to @nums[11:20] into $data[1], so that I could visit, for
> example, the second set of @nums by something like $data[1][5] to get
> 15.
>
> Is this possible for Perl anyway?


my @nums = 1 .. 20;
my @data;

for ( my $i=0; $i<=$#nums; $i=$i+10 ) { # assigns references to
push @data, [ @nums[$i..$i+9] ]; # copies of respective
} # array slice to @data

print $data[1][5]; # prints 16

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
 
 
 
Mirco Wahab
Guest
Posts: n/a
 
      07-29-2007
Rick wrote:
> In C we can store a set of pointers which point to different arrays
> into an array of pointer. This way we could fast access different
> array by looking it up in this pointer array. Is there anyway to do
> this in Perl. I've been trying different things and no luck so far.
>
> LIke:
> @nums = (1 .. 20);
>
> I want to store the reference to @nums[1..10] into $data[0], and the
> reference to @nums[11:20] into $data[1], so that I could visit, for
> example, the second set of @nums by something like $data[1][5] to get
> 15.
>
> Is this possible for Perl anyway?


No

You can't do that in Perl because "arrays"
aren't continous memory blocks (C/C++),
but rather _already_ pointer arrays
(pointers to elements as array values)
with a somehow complicated management
built around.

Furthermore, you can't "jump" in the
middle of something arraylike and
expect to find a mechanism there
which treats the rest as a Perl
array.

The only way to come close is the
_copying_ of an array element range
(slice) into a new (anonymous) array,
as Gunnar has already shown.

Regards

M.
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      07-29-2007
Rick wrote:
>
> In C we can store a set of pointers which point to different arrays
> into an array of pointer. This way we could fast access different
> array by looking it up in this pointer array. Is there anyway to do
> this in Perl. I've been trying different things and no luck so far.
>
> LIke:
> @nums = (1 .. 20);
>
> I want to store the reference to @nums[1..10] into $data[0], and the
> reference to @nums[11:20] into $data[1], so that I could visit, for
> example, the second set of @nums by something like $data[1][5] to get
> 15.


$ perl -le'
@nums = 1 .. 20;
print "@nums";
$data[ 0 ] = [ \@nums[ 0 .. 9 ] ];
$data[ 1 ] = [ \@nums[ 10 .. 19 ] ];
print ${ $data[ 1 ][ 5 ] };
${ $data[ 1 ][ 5 ] } = 0;
print "@nums";
'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 17 18 19 20




John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
 
Reply With Quote
 
Mirco Wahab
Guest
Posts: n/a
 
      07-29-2007
John W. Krahn wrote:
> $data[ 0 ] = [ \@nums[ 0 .. 9 ] ];
> $data[ 1 ] = [ \@nums[ 10 .. 19 ] ];


This usage of slice reference is something I
didn't consider. So Bellovins word was right
again: "any software problem can be solved by
adding another layer of indirection."

"anonymous slice reference" - thanks
for pointing me on this.

Regards

M.
 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      07-29-2007
Mirco Wahab wrote:
> John W. Krahn wrote:
>> $data[ 0 ] = [ \@nums[ 0 .. 9 ] ];
>> $data[ 1 ] = [ \@nums[ 10 .. 19 ] ];

>
> This usage of slice reference is something I
> didn't consider. So Bellovins word was right
> again: "any software problem can be solved by
> adding another layer of indirection."
>
> "anonymous slice reference"


AFAIU, they don't really refer to the slice, but rather to arrays which
in turn refer to the individual elements.

C:\>perl -MData:umper -e "@nums=1..20;print Dumper [ \@nums[0..9] ]"
$VAR1 = [
\1,
\2,
\3,
\4,
\5,
\6,
\7,
\8,
\9,
\10
];

C:\>

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
attn.steven.kuo@gmail.com
Guest
Posts: n/a
 
      07-30-2007
On Jul 29, 11:58 am, Mirco Wahab <(E-Mail Removed)> wrote:
> Rick wrote:
> > In C we can store a set of pointers which point to different arrays
> > into an array of pointer. This way we could fast access different
> > array by looking it up in this pointer array. Is there anyway to do
> > this in Perl. I've been trying different things and no luck so far.

>
> > LIke:
> > @nums = (1 .. 20);

>
> > I want to store the reference to @nums[1..10] into $data[0], and the
> > reference to @nums[11:20] into $data[1], so that I could visit, for
> > example, the second set of @nums by something like $data[1][5] to get
> > 15.

>
> > Is this possible for Perl anyway?

>
> No
>
> You can't do that in Perl because "arrays"
> aren't continous memory blocks (C/C++),
> but rather _already_ pointer arrays
> (pointers to elements as array values)
> with a somehow complicated management
> built around.
>
> Furthermore, you can't "jump" in the
> middle of something arraylike and
> expect to find a mechanism there
> which treats the rest as a Perl
> array.
>
> The only way to come close is the
> _copying_ of an array element range
> (slice) into a new (anonymous) array,
> as Gunnar has already shown.




You can try the tie function (perldoc perltie). E.g.,

package Tie::Slice;
use Tie::Array;
@ISA = qw/Tie::Array/;

sub TIEARRAY {
my $class = shift;
my $aref = shift;
my $offset = shift;
my $length = shift || (@$aref - $offset);
return bless {
AREF => $aref,
OFFSET => $offset,
LENGTH => $length,
}, $class;
}

sub FETCH {
my ($self, $index) = @_;
if ($index >= 0) {
return $self->{AREF}->[$self->{OFFSET}+$index];
} else {
my $subtracted = $self->{OFFSET} + $self->{LENGTH};
return $self->{AREF}->[$index - $subtracted];
}
}

sub FETCHSIZE {
my ($self) = @_;
return $self->{LENGTH};
}

# no methods added for writing to array (e.g., STORE, STORESIZE,
etc.).

package main;
use strict;
use warnings;

my @nums = ( 1 .. 20 );
my (@first_half, @second_half);
tie @first_half, 'Tie::Slice', \@nums, 0, 10;
tie @second_half, 'Tie::Slice', \@nums, 10;
my @data = (\@first_half, \@second_half);

print $data[1][5];


__END__

Note that changes made to @nums will be automatically
reflected in @data (but not visa-versa since I've
only implemented the methods needed for "reading" in
Tie::Slice).

--
Regards,
Steven



 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      07-30-2007
On Jul 29, 6:09 pm, Mirco Wahab <(E-Mail Removed)> wrote:
> John W. Krahn wrote:
> > $data[ 0 ] = [ \@nums[ 0 .. 9 ] ];
> > $data[ 1 ] = [ \@nums[ 10 .. 19 ] ];

>
> This usage of slice reference is something I
> didn't consider. So Bellovins word was right
> again: "any software problem can be solved by
> adding another layer of indirection."
>
> "anonymous slice reference" - thanks
> for pointing me on this.


I wouldn't call it a slice reference. An array slice is a list. The
\ operator applied to a list returns a list of references of the items
in that list. That is:

my @refs = \($a, $b, $c);
is the same as
my @refs = (\$a, \$b, \$c);

So in John's example, you're assigning $data[0] to be a reference to
an array which contains references to each of the first ten elements
of @nums. There is nothing intrinsic about $data[0][2] that
identifies it as a reference to the element immediately prior to
$nums[3]. It's just a list of references to values that happened to
all come from the same array.

Paul Lalli

 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      07-30-2007
On Sun, 29 Jul 2007 18:04:28 -0000, Rick <(E-Mail Removed)>
wrote:

>Subject: question on reference to array slice


Strictly speaking, you can't. But then you can by means of a "nasty
obscure hack":

my @x=1..8
sub refslice { \@_ }
my $ref=refslice @x[2,3];

See <http://perlmonks.org/?node_id=618892> for more info.


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
 
Reply With Quote
 
Ted Zlatanov
Guest
Posts: n/a
 
      07-31-2007
On Sun, 29 Jul 2007 18:04:28 -0000 Rick <(E-Mail Removed)> wrote:

R> Hi, guys
R> In C we can store a set of pointers which point to different arrays
R> into an array of pointer. This way we could fast access different
R> array by looking it up in this pointer array. Is there anyway to do
R> this in Perl. I've been trying different things and no luck so far.

R> LIke:
R> @nums = (1 .. 20);

R> I want to store the reference to @nums[1..10] into $data[0], and the
R> reference to @nums[11:20] into $data[1], so that I could visit, for
R> example, the second set of @nums by something like $data[1][5] to get
R> 15.

R> Is this possible for Perl anyway?

It depends on your purpose. If you aim for speed, just use C (Inline::C
for example). Otherwise, to make your own and everyone else's life
easier, use a function to translate the offsets or a constant. Even
better, explain what you're trying to do; it may be that hashes or
multidimensional arrays or array slices are the right answer for you.

Note you don't have to call the offset function every time, only at the
beginning to find out the offset. So it's not a big speed penalty.

Of course, you can always write your own Tie module, but those are IMHO
the last resort.

Ted

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Newbyish question about Array slice method RubyRedRick Javascript 4 06-01-2008 09:37 PM
Array slice to end of array of indeterminate size niall.macpherson@ntlworld.com Perl Misc 9 05-22-2006 06:34 PM
array.slice() question Christopher Benson-Manica Javascript 4 12-06-2005 08:53 PM
array slice question kr Perl 3 08-13-2004 07:39 PM
slice of multidimensional array Dave Bazell Perl 2 07-24-2003 11:17 PM



Advertisments