Question

I have two arrays which contain objects. I need to push the objects from the second array into the first array's expense_id-related object as a child element of a new expense_taxes property.

$array1 = [
    (object) [
        'expense_id' => 475,
        'expense_name' => 'DRAY',
        'expense_unit_cost' => 270.00
    ],
    (object) [
        'expense_id' => 476,
        'expense_name' => 'FUEL',
        'expense_unit_cost' => 32.40
    ],
];

$array2 = [
    (object) [
        'waybill_id' => 20005044,
        'expense_id' => 475,
        'tax_select' => 'tax1',
        'tax_id' => 1,
        'tax_name' => 'GST 5%',
        'tax_no' => null,
        'tax_value' => 13.5000
    ],
    (object) [
        'waybill_id' => 20005044,
        'expense_id' => 475,
        'tax_select' => 'tax2',
        'tax_id' => 2,
        'tax_name' => 'QST 9.975%',
        'tax_no' => null,
        'tax_value' => 26.9325
    ],
    (object) [
        'waybill_id' => 20005044,
        'expense_id' => 476,
        'tax_select' => 'tax1',
        'tax_id' => 1,
        'tax_name' => 'GST 5%',
        'tax_no' => null,
        'tax_value' => 1.6200
    ],
    (object) [
        'waybill_id' => 20005044,
        'expense_id' => 476,
        'tax_select' => 'tax2',
        'tax_id' => 2,
        'tax_name' => 'QST 9.975%',
        'tax_no' => null,
        'tax_value' => 3.2319
    ],
];

Desired result:

array (
  0 => 
  (object) array(
     'expense_id' => 475,
     'expense_name' => 'DRAY',
     'expense_unit_cost' => 270.0,
     'expense_taxes' => 
    array (
      0 => 
      (object) array(
         'waybill_id' => 20005044,
         'expense_id' => 475,
         'tax_select' => 'tax1',
         'tax_id' => 1,
         'tax_name' => 'GST 5%',
         'tax_no' => NULL,
         'tax_value' => 13.5,
      ),
      1 => 
      (object) array(
         'waybill_id' => 20005044,
         'expense_id' => 475,
         'tax_select' => 'tax2',
         'tax_id' => 2,
         'tax_name' => 'QST 9.975%',
         'tax_no' => NULL,
         'tax_value' => 26.9325,
      ),
    ),
  ),
  1 => 
  (object) array(
     'expense_id' => 476,
     'expense_name' => 'FUEL',
     'expense_unit_cost' => 32.4,
     'expense_taxes' => 
    array (
      0 => 
      (object) array(
         'waybill_id' => 20005044,
         'expense_id' => 476,
         'tax_select' => 'tax1',
         'tax_id' => 1,
         'tax_name' => 'GST 5%',
         'tax_no' => NULL,
         'tax_value' => 1.62,
      ),
      1 => 
      (object) array(
         'waybill_id' => 20005044,
         'expense_id' => 476,
         'tax_select' => 'tax2',
         'tax_id' => 2,
         'tax_name' => 'QST 9.975%',
         'tax_no' => NULL,
         'tax_value' => 3.2319,
      ),
    ),
  ),
)

I have tried to loop one array and check for the expense_id key matching but I can't achieve my final array. Also, I have taken a look at array_merge, array_map and array_intersect.

Was it helpful?

Solution 2

It's all a bit more complicate because the actual arrays of objects are got from ajax into PHP, but, I found myself the answer based on KennyDope suggestion.

If Array1 is $expenses_obj and Array2 is $invoice_taxes_obj

        foreach ($expenses_obj as $key => $expense):
            foreach ($invoice_taxes_obj as $key => $tax):
                if ($expense->expense_id == $invoice_taxes_obj[$key]->expense_id){
                    $expense->taxes[] = (array)$invoice_taxes_obj[$key]; 
                }   
            endforeach;
        endforeach;

And the final result is what I need:

Array
(
[0] => stdClass Object
    (
        [expense_id] => 475
        [expense_name] => DRAY 
        [expense_unit_cost] => 270.00
        [taxes] => Array
            (
                [0] => Array
                    (
                        [waybill_id] => 20005044
                        [expense_id] => 475
                        [tax_select] => tax1
                        [tax_id] => 1
                        [tax_name] => GST 5%
                        [tax_no] => 
                        [tax_value] => 13.5000
                    )

                [1] => Array
                    (
                        [waybill_id] => 20005044
                        [expense_id] => 475
                        [tax_select] => tax2
                        [tax_id] => 2
                        [tax_name] => QST 9.975%
                        [tax_no] => 
                        [tax_value] => 26.9325
                    )

            )

    )

[1] => stdClass Object
    (
        [expense_id] => 476
        [expense_name] => FUEL 
        [expense_unit_cost] => 32.40
        [taxes] => Array
            (
                [0] => Array
                    (
                        [waybill_id] => 20005044
                        [expense_id] => 476
                        [tax_select] => tax1
                        [tax_id] => 1
                        [tax_name] => GST 5%
                        [tax_no] => 
                        [tax_value] => 1.6200
                    )

                [1] => Array
                    (
                        [waybill_id] => 20005044
                        [expense_id] => 476
                        [tax_select] => tax2
                        [tax_id] => 2
                        [tax_name] => QST 9.975%
                        [tax_no] => 
                        [tax_value] => 3.2319
                    )

            )

    )

)

Your comments are welcomed. Thanks for your input.

OTHER TIPS

Try something like...

foreach($object AS $key=>$element){ if ($element->expense_id == 475){ $element->expense_taxes[0] = $stdClass; } }

Using nested loops will result in doing needless cycles. For a more direct approach, assign temporary first level keys to the first array, then iterate the second array and simply relate the expense_id of a given object with the first level key of the first array. When finished iterating, if you don't want the first level associative keys, remove them with array_values().

Code: (Demo)

$array1 = array_column($array1, null, 'expense_id');
foreach ($array2 as $obj) {
    if (isset($array1[$obj->expense_id])) {
        $array1[$obj->expense_id]->expense_taxes[] = $obj;
    }
}
var_export(array_values($array1));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top