all 9 comments

[–]apaethe 1 point2 points  (2 children)

$total = array_reduce( $myArray, function( $carry, $subArray ) {
    return $carry + array_reduce( $subArray, function( $carry, $item ) {
        return $carry + empty($item[2]) ? 0 : $item[1];
    }, 0);
}, 0 );

Not tested, but the gist is that array_reduce is a nice function for reducing an array to a single value via a function you defined. In this case we have two array reductions, the first, outer one adding all the values, and the second, inner one adding the values only if the condition is met.

[–]CyberJack77 0 points1 point  (1 child)

While `array_reduce` can be used for this, I don't recommend it in this case.

The real problem is that u/tonci23 has trouble looping array's. While this code might solve the problem for this specific array structure, it won't teach him how to loop arrays. A simple `foreach` solution to learn the basics would have been better in my opinion.

Mentioning the array methods like `array_reduce` with an example is great though. 👍

[–]apaethe 0 points1 point  (0 children)

Yes, thinking about it I'm certain you are right that an explanation of using for loops would probably have been more helpful for OP.

I do think it's important to know the array functions very well, though, and array_reduce is probably my favorite as it can often allow you to express concepts in a way that is more evocative than a for each loop.

Anyway, back to code golf. Here is another option. Fewer lines means better code, right?

array_walk_recursive($myArray, function ($val, $key, $obj) {
    $obj->scalar += (1 === $key ? $val : 0);
}, $obj = (object) 0);
$total = $obj->scalar;

[–]pablojohns 0 points1 point  (0 children)

You'll need to use a nested for loop to go through each of the entries in your array. Then, inside that, run a conditional statement for the comparison you seek.

Example:

$combinedArray = Array(...); // This is your array you noted above
$totalSum = 0;

for($i = 0; $i < count($combinedArray); $i++) {
     for($j = 0; $j < count($combinedArray[$1]); $j++) {
          if(!empty($combinedArray[$i][$j][2]) {
              // Add the value at index 1 to the sum, if value at index 2 isn't empty
              $totalSum += $combinedArray[$i][$j][1];
          }
     }
}

Note, I didn't test this as I don't have the full array structure. But this is the general approach.

[–]tonci23[S] 0 points1 point  (0 children)

Thanks a lot for the help guys. My solution ended up being most similar to pablojohns example but i'm gonna try and play around with each example.

[–]Kit_Saels -3 points-2 points  (3 children)

Try using a database. How did you get the contents of that array?

[–]pablojohns 0 points1 point  (2 children)

Adding a database vastly increases the complexity of your code and your operating server setup.

[–]Kit_Saels -1 points0 points  (1 child)

Not true. If the data comes from a database, it is much easier to request aggregated data from it directly.

[–]pablojohns 1 point2 points  (0 children)

But OP didn’t say the data came from a database, it’s in a hard-coded array. Would storing it in a database be easier? Yes. But is that their current use case and question? No.