Jump to content

while when not set


AV1611

Recommended Posts

lets say you have an array like this:

[3]=>1
[4]=>2
[5]=>3
[6]=>4
([0]-[2] is missing on purpose, could be different range of numbers)

in $arr[]
and simular in $arr2[]

and you do this:
$av=0;
while ($av<=365){
$data[$av]=($arr[$av]+$arr2[$av])/2;
$av++;
}

if (obviously) gives me
Notice: Undefined offset: 0 in c:\inetpub\wwwroot\production\array2.php on line 125

because it is not in the array... how do I do it?
(Is it foreach? I can't figure out how to do the foreach)
Link to comment
Share on other sites


You mean you have two arrays with the same keys and you want their average for values with the same key?

Try:[code]$a1 = array;
$a2 = array;
$data = array();
// ....
foreach ($a1 as $key => $value) $data[$key] = ($value + $a2[$key]) / 2;
// ... or ...
foreach (array_keys($a1) as $key) $data[$key] = ($a1[$key] + $a2[$key]) / 2;
// if you're sure the keys exist in both arrays, then that's fine.  Otherwise, you might want to use some error checking (like array_key_exists() or isset()).
[/code]
Link to comment
Share on other sites

If you don't need to preserve the keys, you can use the [a href=\"http://www.php.net/manual/en/function.array-map.php\" target=\"_blank\"]array_map()[/a] function. If you need to preserve the keys, use foreach(). The following example shows how to use each:
[code]<?php
$arr = array();
$arr[2] = 3;
$arr[3] = 6;
$arr[5] = 10;

$arr2 = array();
$arr2[2] = 34;
$arr2[3] = 2;
$arr2[5] = 23;

function test_array_map($a1, $a2)
{
    return(($a1 + $a2)/2);
}

$data = array_map(test_array_map,$arr,$arr2);
echo '<pre>' . print_r($data,true) . '</pre>';

$data1 = array();
foreach($arr as $key => $value)
    $data1[$key] = ($value + $arr2[$key])/2;
echo ' ----------------------<br>';
echo '<pre>' . print_r($data1,true) . '</pre>';
?>[/code]

Ken
Link to comment
Share on other sites

thanks, but you just fingered my real problem:

the two arrays are NOT in sync...

I need to do two queries, both for the last 365 days,

the problem is, there will be some days where the data is in one, the other, or both...

What I need to do is this:

so the first query, and build an array,
build the second query, and build an array,

then create a third array that is the average of each date that had a result in EITHER query, then:
if both exist, take the average
if only in the first, then put that in the average array
if only in the second, then put that in the avage array

here is the full script as I have it now... I developed with random number generator, and works great, as long as there is 365 days of data... but the database only has a few days in it, so the script won't start working until next year LOL :\

[code]
$result = mysql_query("create temporary table SILK (Select
products.COMP_COUNT,runtimes.HOURS,runtimes.QTY,runtimes.
DATE_RUN,runtimes.LINE,runtimes.PN,runtimes.SIDE
From products Inner Join runtimes ON runtimes.PN = products.PART_NO)");
$result2=mysql_query("select DATE_RUN, sum((QTY/HOURS)*COMP_COUNT) as compperhour from SILK where LINE='1' group by DATE_RUN");
    while ($row=mysql_fetch_array($result2))
            {$data[]=$row[1];}
$result3=mysql_query("select DATE_RUN, sum((QTY/HOURS)*COMP_COUNT) as compperhour from SILK where LINE='2' group by DATE_RUN");
    while ($row=mysql_fetch_array($result3))
            {$data2[]=$row[1];}
// must be oldest first
$size = count($data);
$size = count($data);
$size3 = count($data);
//query1
$avgs = $sums = $nums = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp = array_slice($data, $i, 30);
     $s = array_sum($tmp);
     if($i<=28){$avgs[$i]=$tmp[$i];
         }
     $avgs[$i+29] = $s/30;
     $nums[$i+29] = join (',',$tmp);
     $sums[$i+29] = $s;
    }
$q=0;
if(isset($avgs[$q])){
        while($q<=28){
            $avgs[$q]=$avgs[29];
            $q++;
            }
        }
$f=0;
KSORT($avgs);
//query2
$avgs2 = $sums2 = $nums2 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp2 = array_slice($data2, $i, 30);
     $s2 = array_sum($tmp2);
     if($i<=28){$avgs2[$i]=$tmp2[$i];}
     $avgs2[$i+29] = $s2/30;
     $nums2[$i+29] = join (',',$tmp2);
     $sums2[$i+29] = $s2;
    }
$q=0;
$f=0;
KSORT($avgs2);
//query2
$avgs2 = $sums2 = $nums2 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp2 = array_slice($data2, $i, 30);
     $s2 = array_sum($tmp2);
     if($i<=28){$avgs2[$i]=$tmp2[$i];}
     $avgs2[$i+29] = $s2/30;
     $nums2[$i+29] = join (',',$tmp2);
     $sums2[$i+29] = $s2;
    }
$q=0;
if(isset($avgs[$q])){
    while($q<=28)
    {$avgs2[$q]=$avgs2[29];
    $q++;}
    }
$f=0;
KSORT($avgs2);
//query3
$av=0;
while ($av<=365){
    $data4[$av]=($data[$av]+$data2[$av])/2;
    $av++;
    }
$avgs3 = $sums3 = $nums3 = array();
for ($i = 0; $i < $size-29; $i++) {
     $tmp3 = array_slice($data4, $i, 30);
     $s3 = array_sum($tmp3);
     if($i<=28){$avgs3[$i]=$tmp3[$i];}
     $avgs3[$i+29] = $s3/30;
     $nums3[$i+29] = join (',',$tmp3);
     $sums3[$i+29] = $s3;
    }
$q=0;
while($q<=28)
{$avgs3[$q]=($avgs[$q]+$avgs2[$q])/2;
$q++;}
$f=0;
KSORT($avgs3);
// Define .PNG image
header("Content-type: image/png");
$imgWidth=913;
$imgHeight=500;
// Create image and define colors
$image=imagecreate($imgWidth, $imgHeight);
$colorWhite=imagecolorallocate($image, 255, 255, 255);
$colorGrey=imagecolorallocate($image, 220,220,220);
$colorBlue=imagecolorallocate($image, 0,0,255);
$colorBlue2=imagecolorallocate($image, 200,200,255);
$colorBlack=imagecolorallocate($image, 0,0,0);
$colorRed=imagecolorallocate($image, 255,0,0);
$colorMagenta=imagecolorallocate($image, 255,0,255);
// Create border around image
// right vert
imageline($image, 912, 500, 912, 0, $colorBlack);
// bottom horiz
imageline($image, 0,499,912,499, $colorBlack);//
// top horiz
imageline($image, 912, 0, 0, 0, $colorBlack);
// left vert
imageline($image, 0, 0, 0, 500, $colorBlack);
// some guide lines
imageline($image, 0, 101, 912, 101, $colorBlack);
imageline($image, 0, 201, 912, 201, $colorBlack);
imageline($image, 0, 301, 912, 301, $colorBlack);
imageline($image, 0, 401, 912, 401, $colorBlack);
imageline($image, 224, 0, 224, 500, $colorBlack);
imageline($image, 449, 0, 449, 500, $colorBlack);
imageline($image, 674, 0, 674, 500, $colorBlack);
// Create grid i<52 means 52 verticals
for ($i=1; $i<365;){
//H
imageline($image, $i*2.5, 0, $i*2.5, 913, $colorGrey);
//V
imageline($image, 0, $i*25, 913, $i*25, $colorGrey);
$i++;
}
// $graphValuesR = array_reverse($graphValues);
// Create line graph
// $avgs = array_reverse($avgs);
// imageline(x1,y1,x2,y2)

//query1 - 30 day rolling avg
for ($i=0; $i<365; $i++){
    if (isset($avgs[$i+1])) {
    imageline($image,
    ($i*2.5),(500-($avgs[$i])*25/1000*2 ),
    (($i+1)*2.5),(500-($avgs[$i+1])*25/1000*2 ),
    $colorBlue);
    }
}
//query2
for ($i=0; $i<365; $i++){
    if (isset($avgs2[$i+1])) {
    imageline($image,
    ($i*2.5),(500-($avgs2[$i])*25/1000*2 ),
    (($i+1)*2.5),(500-($avgs2[$i+1])*25/1000*2 ),
    $colorRed);
    }
}
//query3
for ($i=0; $i<365; $i++){
    if (isset($avgs3[$i+1])) {
    imageline($image,
    ($i*2.5),(500-($avgs3[$i])*25/1000*2 ),
    (($i+1)*2.5),(500-($avgs3[$i+1])*25/1000*2 ),
    $colorMagenta);
    }
}
// Output graph and clear image from memory
imagepng($image);
imagedestroy($image);

[/code]
Link to comment
Share on other sites

Oh, that's a little different.

If I'm reading your code correctly, you could do something like the following where you load up an inital array with the values from your query, keyed by the date, then run through the second dataset, averaging only if the key/value is already set:

[code]
$data_average = array();
foreach ($data as $value) $data_average[$value['DATE_RUN']] = $value['compperhour'];
foreach ($data2 as $value) {
    if (isset($data_average[$value['DATE_RUN']])) {
        $data_average[$value['DATE_RUN']] = ($data_average[$value['DATE_RUN']] + $value['compperhour']) / 2;
    } else {
        $data_average[$value['DATE_RUN']] = $value['compperhour'];
    }
}
[/code]

If you need to flesh out the rest of the array where there are missing values, might I suggest using a combination of PHP's date functions. If you are doing this, say, by calender year, you might create a loop that increments [b]date('Y-m-d',strtotime("2006-01-01") + 86400*$i)[/b] to $i < 365.

Does that scratch where it itches?


(Btw, you might be able to do that same MySQL query without the temp table...)
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.