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

Hi Monks,

I have two arrays corresponding to data points on a graph - e.g one array contains the x-values, the other contains the y-values (all are in order so $x_value[0] is paired with $y_value[0] etc). I basically want a quick way of looking up each pair from the two arrays are re-formating them like so: (value_from_y , value_from_x); The problem is that I am working within a foreach loop iterating over 96 lines (and doing this for each line) and it is also within a CGI which chocked after ~ line 22 with my effort below. If anyone knows of a more efficient way to do this I would be very happy.

for (0 .. scalar (@x_values)) { $gradient_array[$_] = '(' . $x_values[$_] . ',' . $y_values[$_] . +')'; }

update (broquaint): fixed formatting

Replies are listed 'Best First'.
Re: Pairing values from two arrays
by broquaint (Abbot) on May 13, 2003 at 09:39 UTC
    my @grads = map "($x_values[$_],$y_values[$_])", 0 .. $#x_values;
    See. the map docs for more info on that most marvellous master of manipulation :)
    HTH

    _________
    broquaint

      Is it really more efficient? I know that sometimes it is beneficiall to just play with the problem and try different versions of code - to spot the real root of the problem. But you don't address his problem directly, or do you?
        Is it really more efficient?
        I got the impression that 'efficient' was more to do with line consumption than CPU cycles, and even if it is do with CPU cycles, map should be just as fast as a foreach if not faster in this situation. Let's see ...
        use strict; use Benchmark 'cmpthese'; my @y_vals = my @x_vals = 1 .. 50; cmpthese(-10, { map => sub { return map "($x_vals[$_],$y_vals[$_])", 0 .. $#x_vals }, for => sub { my @ret; $ret[$_] = "($x_vals[$_],$y_vals[$_])" for 0 .. $#x_vals; return @ret; }, }); __output__ Benchmark: running for, map, each for at least 10 CPU seconds... for: 11 wallclock secs (10.19 usr + 0.00 sys = 10.19 CPU) @ 75 +36.80/s (n=76800) map: 11 wallclock secs (10.34 usr + 0.01 sys = 10.35 CPU) @ 77 +68.31/s (n=80402) Rate for map for 7537/s -- -3% map 7768/s 3% --
        Ever so slightly faster, but essentially negligble. As always, take with a grain of salt. But I'd say that's about as quick as your going to get without going down the dark path of optimization.
        HTH

        _________
        broquaint

      thankyou broquaint - this is exactly what I wanted ;-)
Re: Pairing values from two arrays
by BrowserUk (Patriarch) on May 13, 2003 at 10:20 UTC

    I'm puzzled why you want to convert to arrays of pairs of coordinates into a single array of strings?

    The only use I can see for this is if you are going to display them as part of the html on the page you are generating? Any other use would require you to parse the strings to retrieve the numeric values and that is never going to be efficient which appears to be your main concern.

    I'm completely lost by your description of "The problem is that I am working within a foreach loop iterating over 96 lines (and doing this for each line) and it is also within a CGI which chocked after ~ line 22".

    If you are doing this prior to printing them either the browser as part of your page or to disk somewhere, then there is no point in building a seperate array of strings first. You can just build the strings when you print it.

    A little more explaination of what it is that you are doing, with perhaps a little more of the code would probably get you better answers.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
Re: Pairing values from two arrays
by arturo (Vicar) on May 13, 2003 at 12:21 UTC

    Just a point that I didn't see made in any of the other responses, although broquaint's code doesn't have this problem: scalar @array returns the number of things in the array; but since arrays are 0 indexed, that means that on the last iteration of the loop

    for( 0..scalar(@x_values) )
    you're accessing undefined values in the two arrays you're attempting to coordinate. Perl may be complaining about that if you have warnings on, and if this processing takes place before you output the headers, you might be confuzling your web server. For that reason and others:
    for( 0 .. $#x_values )
    is a better way to write it ( $#ARRAY_NAME is the value of the last index of the array with name ARRAY_NAME ).

    If not P, what? Q maybe?
    "Sidney Morgenbesser"

Re: Pairing values from two arrays
by edoc (Chaplain) on May 13, 2003 at 10:08 UTC

    I think you'd really need to tell us why it "chocked".

    The only things I can think of is that you're running out of time (browser times out) or memory. If it's time, then you're going to need to convert the data "offline" and store it in a usable form. If it's memory then maybe..

    my @x = (3,67,4,2,8,45,23); my @y = (4,7,4,89,6,4,3); my $arrayref = merge(\@x,\@y); undef @y; my @newarray = @$arrayref; undef @x; sub merge{ my ($x,$y) = @_; foreach (@$x){ $_ = '('.$_.','.(shift @$y).')'; } return $x; }

    ;)

    cheers,

    J

Re: Pairing values from two arrays
by Skeeve (Parson) on May 13, 2003 at 09:37 UTC
    What do you want to do with it?
    Do you want to simply have "one array"?
    How about this then:
    @gradient_array= ( \@x_values, \@y_values );
    You can access your pair with:
    $x=$gradient_array[0]->[$index]; $y=$gradient_array[1]->[$index];
    But that's not much better than accessing two arrays, regarding memory.