mdunnbass has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks!

I am trying to find out how to dump arrayB into arrayA as the (new) last element. Kind of like push(), except that rather than adding the elements of arrayB at the end of arrayA as several more elements, you get all of arrayB as the last element of arrayA.

A short (and simplified) explanation of what I'm trying to do:

User supplies a filename, which contains a variable number of text blocks. User then supplies a variable number of strings. Each block of text is read in, piecemeal, and searched for each string. Each pass through saves the position of each match to a string into an array (arrayB). This array of matches to the first string becomes the first element of arrayA. The search is repeated for the second string (a new arrayB), and this array becomes the second element of arrayA, and so on for the number of strings the user desires. Once the first text block has been thoroughly search, arrayA now gets dumped into the first element of arrayC. Then, we progress on to the second text block, and so on from there.

Ideally, I would then format each text block to highlight each string-match in a particular color, based on the position of hits stored in each ArrayB, corresponding to the particular string matched stored in each ArrayA, corresponding to the text block the hits are found in (the position in ArrayC.

So, the length of ArrayC is a variable dictated by the contents of a user input file, the length of each element of ArrayC is ArrayA, which is dictated by the number of strings to be searched for, again dictated by the user, and the position of each of the matches to each string is uncovered by m//, and stored in ArrayB

I hope that makes sense to someone other than me.

Any advice would be greatly appreciated.

TIA,
Matt

  • Comment on appending and array into last element of an array?

Replies are listed 'Best First'.
Re: appending and array into last element of an array?
by ikegami (Patriarch) on Oct 11, 2006 at 16:24 UTC
    You can't store an array in an array, but you can store a reference to one.
    # Saves a reference to the existing array. push(@arrayA, \@arrayB);
    # Creates a new (anon) array and saves a reference to it. push(@arrayA, [ @arrayB ]);
      OK. that sounds good so far, but if I'm doing this in a looping context, and the next time around the loop, the values of @arrayB change, won't that change all of the references as well?

      Also, how could I save the anon array in your second example? setting something equal to the push gives the length of the new array, right? Could I just do

      push(@arrayA, [ @arrayB ]); @new_array = @_;

      would that work?

      And thanks for the quick reply.
      Matt

        OK. that sounds good so far, but if I'm doing this in a looping context, and the next time around the loop, the values of @arrayB change, won't that change all of the references as well?

        It depends on where @arrayB is declared.

        my @arrayA; my @arrayB; while (...) { @arrayB = ...; push(@arrayA, \@arrayB); # XXX }
        my @arrayA; my @arrayB; while (...) { @arrayB = ...; push(@arrayA, [ @arrayB ]); # Ok }
        my @arrayA; while (...) { my @arrayB = ...; push(@arrayA, \@arrayB); # Ok }
        my @arrayA; while (...) { my @arrayB = ...; push(@arrayA, [ @arrayB ]); # Needlessly creating 3rd array. }

        Also, how could I save the anon array in your second example?

        What does "save" mean? Copy? You already have a copy of the array in @arrayB.

Re: appending and array into last element of an array?
by cdarke (Prior) on Oct 11, 2006 at 16:44 UTC
    If I understand your problem correctly, then you might wish to consider using a hash instead. Maybe use the string as the key and the value could be a reference to an array of positions.
Re: appending and array into last element of an array?
by shmem (Chancellor) on Oct 12, 2006 at 09:21 UTC
    Each pass through saves the position of each match to a string into an array (arrayB). This array of matches to the first string becomes the first element of arrayA.

    You need two values here, either position + length or start-positon and end-position of each match. Perl provides the variables @- and @+ for the latter. An example is in perlretut.

    You could store these values in a single string, e.g. "16-25", or store them in an array. To push that array into arrayB, the array's representation has to be a scalar, because there can only be one element in each slot of an array. So, you need an anonymous array which can be accessed via a reference (see e.g. perlreftut).

    my @arrayC; while(defined($textblock) = <>) { my @arrayA = (); foreach my $string (@strings) { my @arrayB = (); while($textblock =~ /$string/) { push @arrayB, [ $-[0], $+[0] ]; } push @arrayA, \@arrayB; } push @arrayC, \@arrayA; }

    Note that we take references to the lexically scoped arrays @arrayA and @arrayB (with the "\" operator, see perlop), which are re-initialized at each pass through their loop block.

    Ideally, I would then format each text block to highlight each string-match in a particular color, based on the position of hits stored in each ArrayB, corresponding to the particular string matched stored in each ArrayA, corresponding to the text block the hits are found in (the position in ArrayC.

    So you need to save your textblocks somewhere to do the formatting, if you don't want to read the file twice. You could store it together with the correspondig matches you've found in @arrayC (instead of storing the matches only):

    push @arrayC, [ $textblock, \@arrayA ];

    -shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: appending and array into last element of an array?
by kabeldag (Hermit) on Oct 12, 2006 at 09:25 UTC
    It sort of makes sense. But not really (ala: 'simple explantation').

    Sounds like CGI/HTML input forms !?
    To try and answer the
      Subject Line ...
    No need to append the elements of array(Y) into the last element of array(X).
    Though it can work if you do some text manipulation, it would be silly.

    I don't really understand the proposition that you have made. But, it would be better to do position tracking via external array's or just a hash, or just multi-dimensional arrays.

    I think I just dont understand your scenario enough. Maybe just use mutli-dimensional arrays, ie; $array[$n][$m].
    There are plenty of ways of doing things :- ).