dynamic access to multidimensional array

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default dynamic access to multidimensional array

    Hi,

    Is it somehow possible to index an array by another array?
    Example:

    @AoA = (
    [ "fred", "barney" ],
    [ "george", "jane", "elroy" ],
    [ "homer", "marge", "bart" ],
    );

    and I have another array

    @ind = ( 0, 1 );

    How can I use @ind to index @AoA to get $AoA[0][1] ?
    (and I *dont* want to write $AoA[$ind[0]][$ind[1]], since this might be dynamic:
    @ind might have length 1,2,3,...)

    Any ideas?

    TIA,

    Stefan
    Stefan Schnitter Guest

  2. Similar Questions and Discussions

    1. creating a multidimensional array
      How can I combine two arrays in cfscript to form one multidimensional array? For example, I have two arrays: firstarray=fred; firstarray=jim;...
    2. Dynamic population of multidimensional array?
      Here is my goal: I have a destructive encryption algorithm I designed. It's similar to MD5, in that it can't be decrypted. The way it works is it...
    3. Multidimensional array: see if 1st key is available
      Hi, I've got an multidimensional array $ret = $country_code; Now I want to see if $countryCode is even in that array, because if it's not, it...
    4. copying a multidimensional array
      Hi: whatz the best way to copy an multidimensional array onto another. I have never used something like clone, just want to know whatz the easiest...
    5. Split multidimensional array into 4 multidimensional arrays
      Hello everyone, I have a multidimensional array that I need to split into 4 multidimensional arrays. I've tried the examples from the...
  3. #2

    Default Re: dynamic access to multidimensional array

    [email]kompakt17@gmx.net[/email] (Stefan Schnitter) writes:
    > Is it somehow possible to index an array by another array?
    > Example:
    >
    > @AoA = (
    > [ "fred", "barney" ],
    > [ "george", "jane", "elroy" ],
    > [ "homer", "marge", "bart" ],
    > );
    >
    > and I have another array
    >
    > @ind = ( 0, 1 );
    >
    > How can I use @ind to index @AoA to get $AoA[0][1] ?
    #!/usr/bin/perl
    use strict;
    use warnings;

    sub index_AoA : lvalue {
    my $v = \shift;
    $v = \$$v->[$_] for @{shift()};
    $$v;
    }

    my @AoA = (
    [ "fred", "barney" ],
    [ "george", "jane", "elroy" ],
    [ "homer", "marge", "bart" ],
    );

    my @ind = ( 0, 1 );

    print index_AoA(\@AoA,\@ind),"\n";

    index_AoA(\@AoA,[1,1]) = 'june';

    print $AoA[1][1],"\n";

    __END__

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley Guest

  4. #3

    Default Re: dynamic access to multidimensional array

    Stefan Schnitter <kompakt17@gmx.net> wrote in comp.lang.perl.misc:
    > Hi,
    >
    > Is it somehow possible to index an array by another array?
    > Example:
    >
    > @AoA = (
    > [ "fred", "barney" ],
    > [ "george", "jane", "elroy" ],
    > [ "homer", "marge", "bart" ],
    > );
    >
    > and I have another array
    >
    > @ind = ( 0, 1 );
    >
    > How can I use @ind to index @AoA to get $AoA[0][1] ?
    > (and I *dont* want to write $AoA[$ind[0]][$ind[1]], since this might be dynamic:
    > @ind might have length 1,2,3,...)
    You'll need a recursive access routine for that. Here is one way to
    write it:

    sub nested_access {
    my $array = shift;
    my ( $i, @rest) = @_;
    @rest ? nested_access( $array->[ $i], @rest) : $array->[ $i];
    }

    Called as

    my $x = nested_access( \ @AoA, 0, 1);

    it will set $x to "barney".

    Anno
    Anno Siegel Guest

  5. #4

    Default Re: dynamic access to multidimensional array

    Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    <URL:news:u9ad9eywat.fsf@wcl-l.bham.ac.uk>:
    `' [email]kompakt17@gmx.net[/email] (Stefan Schnitter) writes:
    `'
    `' > Is it somehow possible to index an array by another array?
    `' > Example:
    `' >
    `' > @AoA = (
    `' > [ "fred", "barney" ],
    `' > [ "george", "jane", "elroy" ],
    `' > [ "homer", "marge", "bart" ],
    `' > );
    `' >
    `' > and I have another array
    `' >
    `' > @ind = ( 0, 1 );
    `' >
    `' > How can I use @ind to index @AoA to get $AoA[0][1] ?
    `'
    `' #!/usr/bin/perl
    `' use strict;
    `' use warnings;
    `'
    `' sub index_AoA : lvalue {
    `' my $v = \shift;
    `' $v = \$$v->[$_] for @{shift()};
    `' $$v;
    `' }
    `'
    `' my @AoA = (
    `' [ "fred", "barney" ],
    `' [ "george", "jane", "elroy" ],
    `' [ "homer", "marge", "bart" ],
    `' );
    `'
    `' my @ind = ( 0, 1 );
    `'
    `' print index_AoA(\@AoA,\@ind),"\n";
    `'
    `' index_AoA(\@AoA,[1,1]) = 'june';
    `'
    `' print $AoA[1][1],"\n";



    Eck. Why so difficult? 'eval' makes it very easy:

    #!/usr/bin/perl

    use strict;
    use warnings;

    my @AoA = ([qw /fred barney/],
    [qw /george jane elroy/],
    [qw /homer marge bart/]);

    my @ind = (0, 1);

    my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    die $@ if $@;

    print $elem, "\n";
    __END__
    barney



    Abigail
    --
    perl -wle 'eval {die ["Just another Perl Hacker"]}; print ${${@}}[$#{@{${@}}}]'
    Abigail Guest

  6. #5

    Default Re: dynamic access to multidimensional array

    Abigail <abigail@abigail.nl> wrote in comp.lang.perl.misc:
    > Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    > <URL:news:u9ad9eywat.fsf@wcl-l.bham.ac.uk>:
    > `' [email]kompakt17@gmx.net[/email] (Stefan Schnitter) writes:
    > `'
    > `' > Is it somehow possible to index an array by another array?
    > `' > Example:
    > `' >
    > `' > @AoA = (
    > `' > [ "fred", "barney" ],
    > `' > [ "george", "jane", "elroy" ],
    > `' > [ "homer", "marge", "bart" ],
    > `' > );
    > `' >
    > `' > and I have another array
    > `' >
    > `' > @ind = ( 0, 1 );
    > `' >
    > `' > How can I use @ind to index @AoA to get $AoA[0][1] ?
    [snip of recursive solution]
    > Eck. Why so difficult? 'eval' makes it very easy:
    >
    > #!/usr/bin/perl
    >
    > use strict;
    > use warnings;
    >
    > my @AoA = ([qw /fred barney/],
    > [qw /george jane elroy/],
    > [qw /homer marge bart/]);
    >
    > my @ind = (0, 1);
    >
    > my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    > die $@ if $@;
    >
    > print $elem, "\n";
    > __END__
    > barney
    The usual security concerns apply if @AoA comes from outside the program.
    I wonder what's more efficient, but not enough to benchmark.

    That aside, the solution is cute, but it looks like cheating. From one
    point of view, it isn't a solution at all. It doesn't solve the problem
    of multi-level indexing but uses the solution built into the Perl interpreter.
    Thus, it gives no insight into the problem.

    Of course, if the task isn't to gain insight but to get it done, it's
    code re-use at its finest.

    Anno
    Anno Siegel Guest

  7. #6

    Default Re: dynamic access to multidimensional array

    Abigail <abigail@abigail.nl> writes:
    > Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    > `' sub index_AoA : lvalue {
    > `' my $v = \shift;
    > `' $v = \$$v->[$_] for @{shift()};
    > `' $$v;
    > `' }
    > Eck. Why so difficult? 'eval' makes it very easy:
    >
    > my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    > die $@ if $@;
    Thankyou! I'm planning to do a talk at YAPC::Europe::2004 about some
    of the issues surrounding the good the bad and the ugly uses of
    eval-string.

    I needed some good non-trivial examples where a simple eval solution
    exists to a problem and were it looks amazingly elegant at one level
    but is actually aborrently ugly to an experienced programmer.

    BTW: You should have put some smileys in there. Some people may have
    actually thought you were serious. I trust you _were_ joking.

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley Guest

  8. #7

    Default Re: dynamic access to multidimensional array

    [email]anno4000@lublin.zrz.tu-berlin.de[/email] (Anno Siegel) writes:
    > Abigail <abigail@abigail.nl> wrote in comp.lang.perl.misc:
    >
    > > my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    >
    > The usual security concerns apply if @AoA comes from outside the program.
    Unless I'm missing something, you mean @ind, not @AoA.

    --
    \\ ( )
    . _\\__[oo
    .__/ \\ /\@
    . l___\\
    # ll l\\
    ###LL LL\\
    Brian McCauley Guest

  9. #8

    Default Re: dynamic access to multidimensional array

    Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    <URL:news:u94qzlzzrm.fsf@wcl-l.bham.ac.uk>:
    && Abigail <abigail@abigail.nl> writes:
    &&
    && > Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    &&
    && > `' sub index_AoA : lvalue {
    && > `' my $v = \shift;
    && > `' $v = \$$v->[$_] for @{shift()};
    && > `' $$v;
    && > `' }
    &&
    && > Eck. Why so difficult? 'eval' makes it very easy:
    && >
    && > my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    && > die $@ if $@;
    &&
    && Thankyou! I'm planning to do a talk at YAPC::Europe::2004 about some
    && of the issues surrounding the good the bad and the ugly uses of
    && eval-string.
    &&
    && I needed some good non-trivial examples where a simple eval solution
    && exists to a problem and were it looks amazingly elegant at one level
    && but is actually aborrently ugly to an experienced programmer.

    I guess I'm not an experienced programmer then.

    && BTW: You should have put some smileys in there. Some people may have
    && actually thought you were serious. I trust you _were_ joking.

    I wasn't. Being able to do stuff like this is what makes Perl Perl.
    I really hate dogma's like "you can't use string eval". Restricting
    yourself to part of the language is something for the FWP mailinglist,
    but a serious programmer should use the full power of the language.

    And the whining "but if @ind comes from the outside, it's dangerous"
    gets old fast. 'unlink $file' is dangerous if $foo comes from the outside
    as well, but that's no reason to not use unlink. I'm fully aware that if
    you run on behalve of some other user (suid, CGI, etc) there are issues -
    issues that go much further than string eval. But the vast majority of
    the programs I write runs under the same UID as the user invoking it. If
    the user wants to screw himself, he doesn't need my programs to do so.


    Abigail
    --
    INIT {print "Perl " }
    END {print "Hacker\n"}
    CHECK {print "another "}
    BEGIN {print "Just " }
    Abigail Guest

  10. #9

    Default Re: dynamic access to multidimensional array

    Abigail <abigail@abigail.nl> wrote in message news:<slrnblsghc.e97.abigail@alexandra.abigail.nl> ...
    > Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
    > <URL:news:u94qzlzzrm.fsf@wcl-l.bham.ac.uk>:
    > && Abigail <abigail@abigail.nl> writes:
    > &&
    > && > my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    > &&
    > && [...] looks amazingly elegant at one level
    > && but is actually aborrently ugly to an experienced programmer.
    >
    > I guess I'm not an experienced programmer then.
    "When I was a child I spoke as a child I understood as a child I
    thought as a child; but when I became a man I put away childish
    things." I Cor. xiii. 11.

    20 years ago I was a child and I was an inexperienced programmer (~5y)
    and my language of choice was "Beeb BASIC"[1].

    It happens that Beeb BASIC has an EVAL() function very similar to
    Perl's eval().

    It was also worth noting that the Beeb had only 7K of user RAM in it's
    highest resolution/depth graphics modes so anything that saved a byte
    was good.

    I used to delight in things like this.

    Now I program for a living.

    Now I maintain code written by others.

    Now I code libraries that are reused.

    Now I code that others maintain.

    Now I don't do things like that execpt under very special
    circumstances (like scripts that I know are to be used once and thown
    away).
    > && I trust you _were_ joking.
    >
    > I wasn't.
    Oh dear.
    > Being able to do stuff like this is what makes Perl Perl.
    Agreed.
    > I really hate dogma's like "you can't use string eval".
    Me too.
    > Restricting
    > yourself to part of the language is something for the FWP mailinglist,
    > but a serious programmer should use the full power of the language.
    Using the full power of the language does not mean that when there is
    a choice of tools you use a technique just because you haven't used it
    for while.
    > And the whining "but if @ind comes from the outside, it's dangerous"
    > gets old fast.
    Using eval here is not ugly because it is insecure. It's very hard to
    explain the real reason. Which is why people usually end up saying
    "it's dangerous". But that's not the real reason.

    It's not really a security problem since if you've got tainting on
    @ind can't come from an external source unless it's been laundered, in
    which case it's probably been laundered with /^(\d+)$/ so that's OK.

    It is ugly because it blurs the code/data divide for no beniefit.

    The eval approach is not really any shorter (if you reduce the refs
    approach to it's minimum inlined form too), and the eval approach is
    certainly slower.

    timethese 100000 => {
    eval => sub {
    my $elem = do {
    local $" = "][";
    eval "\$AoA [@ind]";
    };
    },
    refs => sub {
    my $elem = \@AoA;
    $elem = $elem->[$_] for @ind;
    },
    }

    Benchmark: timing 100000 iterations of eval, refs...
    eval: 6 wallclock secs ( 5.84 usr + 0.06 sys = 5.90 CPU)
    @ 16949.15/s (n=100000)
    refs: 1 wallclock secs ( 0.59 usr + 0.00 sys = 0.59 CPU)
    @ 169491.53/s (n=100000)

    Blurring the code/data line is a very powerfull tool and I think many
    people are undely scared of using it when it is sensible to do so.
    Indeed that is to be topic of my talk in Belfast.

    But I don't think this is a case when it is sensible. One of my major
    tasks over the next few months is to pin down exactly why I think
    that.
    > 'unlink $file' is dangerous if $foo comes from the outside
    > as well, but that's no reason to not use unlink. I'm fully aware that if
    > you run on behalve of some other user (suid, CGI, etc) there are issues -
    > issues that go much further than string eval. But the vast majority of
    > the programs I write runs under the same UID as the user invoking it. If
    > the user wants to screw himself, he doesn't need my programs to do so.
    If you take a look at Message-ID: <u9d78x4ave.fsf@wcl-l.bham.ac.uk>
    [url]http://groups.google.com/groups?selm=u9d78x4ave.fsf%40wcl-l.bham.ac.uk[/url]
    and the thread containing it you will see that I'm usually on your
    side of this argument.

    [1] [url]http://www.bbcbasic.com/[/url]
    nobull@mail.com Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139