-2

I need to find the average of all AdjClose values in my two dimensional array.

I have an array stored in a variable $data. It looks like this:

["data"]=>
  array(22) {
    [0]=>
    object(stdClass)#234 (7) {
      ["Date"]=>
      string(10) "2016-08-31"
      ["Open"]=>
      string(9) "767.01001"
      ["High"]=>
      string(10) "769.090027"
      ["Low"]=>
      string(10) "765.380005"
      ["Close"]=>
      string(10) "767.049988"
      ["Volume"]=>
      string(7) "1247400"
      ["AdjClose"]=>
      string(10) "767.049988"
    }
    [1]=>
    object(stdClass)#240 (7) {
      ["Date"]=>
      string(10) "2016-08-30"
      ["Open"]=>
      string(10) "769.330017"
      ["High"]=>
      string(10) "774.466003"
      ["Low"]=>
      string(10) "766.840027"
      ["Close"]=>
      string(10) "769.090027"
      ["Volume"]=>
      string(7) "1127100"
      ["AdjClose"]=>
      string(10) "769.090027"
    }

It has around 22 entries and I want to iterate through every ["AdjClose"] and calculate the average of these numbers.

From what I understand, I should write something like: if(@$data->data->AdjClose) but this is where my problems begin.

Can someone explain to me please how to iterate through the objects/rows access and store the AdjClose values and calculate the average?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Alan
  • 213
  • 1
  • 13

3 Answers3

4

Here's an example of an iterative solution, since you were asking about how that would work:

// initialize sum and total
$sum = 0;
$total = 0;

foreach ($data->data as $obj) {
    if (isset($obj->AdjClose)) {   // verify that the current object has an AdjClose
        $sum += $obj->AdjClose;    // add it to the sum
        $total++;                  // increment the count
    }
}
echo $sum / $total;                // display the average

I added the if (isset($obj->AdjClose) check because you asked about if(@$data->data->AdjClose). I thought that implied that AdjClose might not be present in some of the objects. If that is the case, I wanted to show how to check for it rather than using the error suppression operator (@). If you want items without AdjClose to be included in the average as zeroes, you can move the $total++ outside the if block.


If you have PHP 7, you can also do this using array_column (but again, unless you want to include missing AdjClose properties in your average as zeroes, only use this if AdjClose is defined on all of the objects).

$average = array_sum(array_column($data->data, 'AdjClose')) / count($data->data)
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
3

Arrays are processed using one of the looping structures I suggest foreach in this case

$cnt = 0;
$tot = 0;
foreach ( $data['data'] as $obj ) {

    $cnt++;
    $tot += (float)$obj->AdjClose;
}

$mean = $tot / $cnt;
echo 'The mean is ' . $mean;
RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
1

Simple code:

$total = 0;
foreach($data['data'] as $item) {
    $total += (float)item->AdjClose;
}

$res = $total / count($data['data']);
Andrej
  • 7,474
  • 1
  • 19
  • 21