input
input

Reputation: 7519

Calculate a new column and remove other columns within nested objects of a multidimensional object

I receive an object from an API which has this structure:

{
    "success": true,
    "quoteId": 11,
    "abcValue": 0,
    "priceResponse": [
        {
            "priceId": 1263,
            "fPrice": 37.14,
            "grossPrice": 44.7,
            "priceType": "ABC"
        },
        {
            "priceId": 1263,
            "fPrice": 37.14,
            "grossPrice": 44.7,
            "priceType": "ABC"
        },
        {
            "priceId": 1266,
            "fPrice": 550.14,
            "grossPrice": 544.7,
            "priceType": "DEF"
        }
    ]
}

I want to loop through the PriceResponse array to add a new calculated property and remove unneeded properties from each child object. The best way I figured to do this was to create another array. However I can't seem to get it working.

My coding attempt:

$output_array = json_decode($output);
$modified_array = array();
$priceResultArray = array();

foreach($output_array as $j => $item) {
                
    foreach($output_array->priceResponse as $i => $field) {
        $percent =  $field->grossPrice * 10 / 100;
        $customPrice =  $field->grossPrice + $percent;

        $priceResultArray['priceId'] = $field->priceId;
        $priceResultArray['customPrice'] = $customPrice;
    }

    $modified_array['success'] = $output_array->success;
    $modified_array['quoteId'] = $output_array->quoteId;
    $modified_array['priceResponse'] = $priceResultArray;
}
var_dump($modified_array);

This is the output of the modified array - it only shows the last result of the priceResultArray:

array(3) {
  ["success"]=>
  bool(true)
  ["quoteId"]=>
  int(0011)
  ["priceResult"]=>
  array(5) {
    ["priceId"]=>
    int(1266)
    ["customPrice"]=>
    float(599.17)
  }
}

Upvotes: 1

Views: 89

Answers (3)

mickmackusa
mickmackusa

Reputation: 47894

I think an array_map() call and whole sub-object declarations in the callback represent a cleaner implementation. The new price calculation can be mathematically simplified as well. The data payload can just as easily be processed as a multidimensional array, but I've decoded the JSON into an object to align with your coding attempt. Demo

$object = json_decode($response);

$object = (object)[
    'success' => $object->success,
    'quoteId' => $object->quoteId,
    'priceResponse' => array_map(
        fn($item) => [
            'priceId' => $item->priceId,
            'customPrice' => $item->grossPrice * 1.1,
        ],
        $object->priceResponse
    )
];

print_r($object);

Output:

stdClass Object
(
    [success] => 1
    [quoteId] => 11
    [priceResponse] => Array
        (
            [0] => Array
                (
                    [priceId] => 1263
                    [customPrice] => 49.17
                )
            [1] => Array
                (
                    [priceId] => 1263
                    [customPrice] => 49.17
                )
            [2] => Array
                (
                    [priceId] => 1266
                    [customPrice] => 599.17
                )
        )
)

Upvotes: 0

Barmar
Barmar

Reputation: 780889

You don't need the outer loop. $output_array is a single object, not an array. You're looping over the properties, but never doing anything with $j or $item.

And instead of creating a new array, you can simply modify the objects in the original priceResponse array.

$output_array = json_decode($output);
foreach ($output_array->priceResponse as $field) {
    $percent =  $field->grossPrice * 10 / 100;
    $customPrice =  $field->grossPrice + $percent;
    $field->customPrice = $customPrice;
    unset($field->fPrice);
    unset($field->priceType);
    unset($field->grossPrice);
}

Upvotes: 1

Dmitriy Buteiko
Dmitriy Buteiko

Reputation: 644

You have such output because you put values inside the same keys within your loop. You should create new object on each loop interation. Checkout this code:

$output_array = json_decode($output);
$modified_array = array();
$priceResultArray = array();

foreach($output_array as $j => $item) {

    foreach($output_array->priceResponse as $i => $field) {
        $percent =  $field->grossPrice * 10 / 100;
        $customPrice =  $field->grossPrice + $percent; 

        $singlePriceResult = array();
        $singlePriceResult['priceId'] = $field->priceId;
        $singlePriceResult['customPrice'] = $customPrice;

        $priceResultArray[] = $singlePriceResult;
    }

    $modified_array['success'] = $output_array->success;
    $modified_array['quoteId'] = $output_array->quoteId;
    $modified_array['priceResponse'] = $priceResultArray;

}
var_dump($modified_array);

Upvotes: 1

Related Questions