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

Hi! I have more arrays, they are the results of an html form, and each array may be empty or may have more elements.Every array that has elements I want to put it in another array using join, smth. like this:
@a,@b,@c,@d,@e,@f,@g if(@a){my $test=join(',',@a)} else{ @a is empty I don't put it in $test} if (@a and @b and @c){my $test=join(',',@a).'and'.join(',',@b).'and'.j +oin(',',@c)}
So when my array is not empty I want to put it in $test using join if is empty I don't need it. I relly don't know how to make this selection. Thank you very much for your time.

Replies are listed 'Best First'.
Re: array testing
by TomDLux (Vicar) on Oct 30, 2003 at 15:28 UTC

    I'm afraid you aren't really clear about what the problem is.

    The only thing that's wrong with your demo code is declaring $test should occur before the comdition, rather than inside the then block.

    You can check the array for elements, the way you do above. Sometimes it's simpler to do the join without checking the array: empty arrays generate an empty string.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

Re: array testing
by Roy Johnson (Monsignor) on Oct 30, 2003 at 17:24 UTC
    Something like this ought to do what you want:
    my $test = join(' and ', map { join(',', @$_) } grep(@$_, \@a, \@b, \@c, \@d, \@e, \@f, \@g));
    If that's too obfu for your tastes, dissect it from the inside out and write explicit loops. The grep is going through the list of references to arrays and returning only the ones for which the array has elements. The map is then turning each array into a string of comma-separated values via join, and the top join is putting all those strings together with " and "s.
Re: array testing
by erasei (Pilgrim) on Oct 30, 2003 at 15:31 UTC
    You want to use the 'defined' function to test if your array contains anything. 'defined' will return true if the array has any elements, and will return false if it is A: not defined at all, or B: defined null (@arr = () returns false).
    my @one = ('A', 'B', 'C'); my @two = (); if (defined(@one)) { print "Array one is defined.\n"; } if (defined(@two)) { print "Array two is defined.\n"; }
    will print only:
    Array one is defined.
      You should only use defined on scalars.
      perldoc -f defined says:
      Use of "defined" on aggregates (hashes and arrays) is deprecated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl. You should instead use a simple test for size:
      if (@an_array) { print "has array elements\n" } if (%a_hash) { print "has hash members\n" }

      perldoc -f defined for 5.8.1 (and earlier, I believe) lists defined as deprecated for aggregates. Besides that, an array in scalar context returns the number of elements. Just do:

      if (@one) { ... }
      You want to use the 'defined' function to test if your array contains anything.
      I don't think so. See this code modified from yours:
      @three = (1); @three = (); if (defined(@three)) { print "Array three is defined.\n"; }
      which prints:
      Array three is defined.
      
      (perl 5.6.1)

      This is the reason why using defined in aggregates (= arrays and hashes) is deprecated. Quoting from perlfunc:

      Use of "defined" on aggregates (hashes and arrays) is deprecated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl.
      That's what you're seeing here: array @three has been used, and hasn't completely been freed. A useless test, this "defined(@array)", if you ask me.
    A reply falls below the community's threshold of quality. You may see it by logging in.