question on reference to array slice

Discussion in 'Perl Misc' started by Rick, Jul 29, 2007.

  1. Rick

    Rick Guest

    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
     
    Rick, Jul 29, 2007
    #1
    1. Advertising

  2. 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
     
    Gunnar Hjalmarsson, Jul 29, 2007
    #2
    1. Advertising

  3. Rick

    Mirco Wahab Guest

    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.
     
    Mirco Wahab, Jul 29, 2007
    #3
  4. 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
     
    John W. Krahn, Jul 29, 2007
    #4
  5. Rick

    Mirco Wahab Guest

    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.
     
    Mirco Wahab, Jul 29, 2007
    #5
  6. 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::Dumper -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
     
    Gunnar Hjalmarsson, Jul 30, 2007
    #6
  7. Rick

    Guest

    On Jul 29, 11:58 am, Mirco Wahab <> 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
     
    , Jul 30, 2007
    #7
  8. Rick

    Paul Lalli Guest

    On Jul 29, 6:09 pm, 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" - 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
     
    Paul Lalli, Jul 30, 2007
    #8
  9. On Sun, 29 Jul 2007 18:04:28 -0000, Rick <>
    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,
     
    Michele Dondi, Jul 30, 2007
    #9
  10. Rick

    Ted Zlatanov Guest

    On Sun, 29 Jul 2007 18:04:28 -0000 Rick <> 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
     
    Ted Zlatanov, Jul 31, 2007
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Bazell

    slice of multidimensional array

    Dave Bazell, Jul 23, 2003, in forum: Perl
    Replies:
    2
    Views:
    4,103
  2. kr

    array slice question

    kr, Aug 10, 2004, in forum: Perl
    Replies:
    3
    Views:
    677
  3. Replies:
    9
    Views:
    254
    David Squire
    May 22, 2006
  4. Christopher Benson-Manica

    array.slice() question

    Christopher Benson-Manica, Dec 6, 2005, in forum: Javascript
    Replies:
    4
    Views:
    99
    Christopher Benson-Manica
    Dec 6, 2005
  5. RubyRedRick

    Newbyish question about Array slice method

    RubyRedRick, Jun 1, 2008, in forum: Javascript
    Replies:
    4
    Views:
    129
    Thomas 'PointedEars' Lahn
    Jun 1, 2008
Loading...

Share This Page