0

I recently asked a question about,merging the values of arrays in an array of arrays in php and got the correct answer, how ever it came with problems, ones I cannot figure out regardless of the var dumps or echos I place.

Using the same array example, and the solution provided if I do:

$result = array();
if(is_array($ticketLabors) && !empty($ticketLabors)){
    foreach ($ticketLabors as $innerArray) {
        foreach ($innerArray as $key=>$value) {
            $result[$key] = number_format($result[$key] + $value, 2);
        }
    }
}
var_dump($result);

On an array like such:

array(2) {
  [0]=>
  array(10) {
    ["ticket_labor_ot_travel_c"]=>
    string(5) "34.50"
    ["ticket_labor_travel_c"]=>
    string(5) "23.00"
    ["ticket_labor_ot_c"]=>
    string(5) "34.50"
    ["ticket_labor_reg_c"]=>
    string(5) "23.00"
    ["ticket_labor_user_id"]=>
    string(3) "319"
    ["ticket_labor_tot_hours"]=>
    string(4) "0.50"
    ["ticket_labor_reg_hours"]=>
    string(4) "0.50"
    ["ticket_labor_ot_hours"]=>
    string(4) "0.00"
    ["ticket_labor_travel_hours"]=>
    string(4) "0.00"
    ["ticket_labor_ot_travel_hours"]=>
    string(4) "0.00"
  }
  [1]=>
  array(10) {
    ["ticket_labor_ot_travel_c"]=>
    string(4) "0.00"
    ["ticket_labor_travel_c"]=>
    string(4) "0.00"
    ["ticket_labor_ot_c"]=>
    string(4) "0.00"
    ["ticket_labor_reg_c"]=>
    string(4) "0.00"
    ["ticket_labor_user_id"]=>
    string(1) "0"
    ["ticket_labor_tot_hours"]=>
    string(4) "0.00"
    ["ticket_labor_reg_hours"]=>
    string(4) "0.00"
    ["ticket_labor_ot_hours"]=>
    string(4) "0.00"
    ["ticket_labor_travel_hours"]=>
    string(4) "0.00"
    ["ticket_labor_ot_travel_hours"]=>
    string(4) "0.00"
  }
}

(while keeping in mind, that much like the previous question, the above array might have 70 arrays inside of it)

I get back something like:

array(10) {
  ["ticket_labor_ot_travel_c"]=>
  string(5) "0.00"
  ["ticket_labor_travel_c"]=>
  string(5) "0.00"
  ["ticket_labor_ot_c"]=>
  string(5) "0.00"
  ["ticket_labor_reg_c"]=>
  string(5) "0.00"
  ["ticket_labor_user_id"]=>
  string(5) "0.00"
  ["ticket_labor_tot_hours"]=>
  string(4) "0.00"
  ["ticket_labor_reg_hours"]=>
  string(4) "0.00"
  ["ticket_labor_ot_hours"]=>
  string(4) "0.00"
  ["ticket_labor_travel_hours"]=>
  string(4) "0.00"
  ["ticket_labor_ot_travel_hours"]=>
  string(4) "0.00"
}

One array, with all the arrays of the previous array of arrays compressed and their $key=>$value's added together.

Whats the issue? regardelss of where I var_dump or echo, be it the $key, $value or even the $innerArray

I end up getting tons of notices saying:

Notice: Undefined index: ticket_labor_ot_travel_hours in C:\xampp\htdocs\rms\site\web\module\Report\controller\Index.controller.php on line 146

each notice is different for each key in the $innerArray. So I thought lets do if(isset($key) && isset($value)){ ... } Nope, same issue.

I have checked the outer array and can gaurentee that whats coming in is what I want, all the keys are set.

If your wondering what line 146 is: $result[$key] = number_format($result[$key] + $value, 2);

Any help?

Community
  • 1
  • 1
LogicLooking
  • 916
  • 1
  • 16
  • 32

4 Answers4

0

Firstly, to fix your undefined index problem, add a check above that line:

if(!array_key_exists($key, $result))
    $result[$key] = 0;

Second, the reason your array is compacting is because you're looping two levels deep and your $results array is only one deep. I'm guessing you want to sum the values each iteration and output it at the end... Do it like this:

$result[$key] += $value;

Put your number_format function on when you're outputting the data.

scrowler
  • 24,273
  • 9
  • 60
  • 92
  • Or you could just do: $result[$key] = isset($result[$key]) ? $result[$key] : 0; – HenchHacker Nov 06 '13 at 20:14
  • Pointless, you're reassigning it to itself. – scrowler Nov 06 '13 at 20:15
  • What? No it's not, it's initialising it based on if it already exists and hence, removes the "undefined index" error... i did forget the + $val though in the comment :p – HenchHacker Nov 06 '13 at 20:20
  • psuedo logic for that would be `define $result[$key] = (if it exists) then: ITSELF else: zero;` - there is no need to define it as itself. – scrowler Nov 06 '13 at 20:26
  • There is if it already exists else you redefine it with 0 again and lose it's original value when used in a loop. You can always make it more verbose or just define it outside of the loop first (the normal way). – HenchHacker Nov 06 '13 at 20:30
  • What is the point? There is **no** need to redefine a variable as itself, ever. – scrowler Nov 06 '13 at 20:40
  • How else would you do it in one statement without first declaring it outside of where your using it or wrapping it in an if (which is what the ternary is doing only you don't want to lose the original value if it's already been defined). Anyway, not splitting hairs on this any more but let me know if you find a more compact way without getting undefined errors :) – HenchHacker Nov 06 '13 at 20:43
  • I see your reasoning, but my solution **doesn't** redefine the variable to itself if it doesn't exist. – scrowler Nov 06 '13 at 20:52
0

This is happening first time you access $result[$key] for reading while, it was not initialized. in order to fix that you need to add a check on it if it is not initialized you replace it by 0.

$result[$key] = number_format((array_key_exists($key, $result)?$result[$key]:0) + $value, 2);

Difference between isset and array_key_exists :

$a = array('key1' => 'フーバー', 'key2' => null);

isset($a['key1']);             // true
array_key_exists('key1', $a);  // true

isset($a['key2']);             // false
array_key_exists('key2', $a);  // true

Taken from : Difference between isset and array_key_exists

Community
  • 1
  • 1
Mehdi Karamosly
  • 5,388
  • 2
  • 32
  • 50
0

Try replacing that line that is erroring with:

$result[$key] = isset($result[$key]) ? $result[$key] + $value : 0;

You DON'T want to number format it at that point because once you get to the thousands, you can't add 1,000 + 1 because of the ,

It's true in that you could set the end parameter in the number_format function to not use the thousands separator but it will start increasing the complexity and decrease the performance (since why call a method repeatedly when you aren't properly making use of the functions output until the final call to the function on the last iteration and why increase the complexity when it's not needed at that point in the code?).

You will want to number format it right at the end for example when you display it to the end user. If you want to keep precision to 2 decimal places during the calculation. You are ok to use round($result[$key] + $value, 2) instead.

HenchHacker
  • 1,616
  • 1
  • 10
  • 16
  • he can use `number_format` with `'.',''` to avoid having comma at the end : `number_format((array_key_exists($key, $result)?$result[$key]:0) + $value, 2, '.','')` – Mehdi Karamosly Nov 06 '13 at 20:21
  • True, but it's also affecting the readability of the code you have a ternary inside nested functions all on a single line. Works, but not something I would personally suggest myself. – HenchHacker Nov 06 '13 at 20:23
0

Instead of

$result = array();

use

$result = array_shift($ticketLabors);

This will initialize $result with the first subarray of $ticketLabors, while removing it from the latter.

But you'd better put it right after if.

geomagas
  • 3,230
  • 1
  • 17
  • 27