2

I have the following query result:

Array
(
    [0] => stdClass Object
        (
            [TreatmentLog_ID] => 131
            [DateAdministered] => 2016-07-15
            [Notes] => 
            [Treatment_ID] => 144
            [AmountAdministered] => 1.5
            [Injectable_ID] => 2
            [InjectableName] => Baytril
        )

    [1] => stdClass Object
        (
            [TreatmentLog_ID] => 133
            [DateAdministered] => 2016-07-12
            [Notes] => 
            [Treatment_ID] => 146
            [AmountAdministered] => 1.2
            [Injectable_ID] => 20
            [InjectableName] => Vitamin C
        )

    [2] => stdClass Object
        (
            [TreatmentLog_ID] => 133
            [DateAdministered] => 2016-07-12
            [Notes] => 
            [Treatment_ID] => 147
            [AmountAdministered] => 1.3
            [Injectable_ID] => 21
            [InjectableName] => Vitamin E
        )
)

I'd like to be able to restructure the array into something like this:

Array
(
    [0] => stdClass Object
        (
            [TreatmentLog_ID] => 131
            [DateAdministered] => 2016-07-15
            [Notes] => 
            [Treatments] => Array
                (
                    [0] => stdClass Object
                        (
                            [Treatment_ID] => 144
                            [AmountAdministered] => 1.5
                            [Injectable_ID] => 2
                            [InjectableName] => Baytril
                        )

                )

        )

    [1] => stdClass Object
        (
            [TreatmentLog_ID] => 133
            [DateAdministered] => 2016-07-12
            [Notes] => 
            [Treatments] => Array
                (
                    [0] => stdClass Object
                        (
                            [Treatment_ID] => 146
                            [AmountAdministered] => 1.2
                            [Injectable_ID] => 20
                            [InjectableName] => Vitamin C
                        )

                    [1] => stdClass Object
                        (
                            [Treatment_ID] => 147
                            [AmountAdministered] => 1.3
                            [Injectable_ID] => 21
                            [InjectableName] => Vitamin E
                        )

                )

        )

)

Notice how the second array looks merges the InjectableName, AmountAdministered, Injectable_ID, and Treatment_ID into the array Treatments if the TreatmentLog_ID is a match. Typically working with arrays isn't a problem, but this one has me stumped. Also I cannot change the query.

How could I pull this off in PHP?

4
  • pls provide raw array (using print_r not debug) Commented Jul 17, 2016 at 12:19
  • @pradeep Sorry, fixed Commented Jul 17, 2016 at 12:23
  • where does this item [InjectableTypeName] come from? It doesn't exist in your initial array Commented Jul 17, 2016 at 12:54
  • @RomanPerekhrest It's irrelevant data that was excluded from my query. Commented Jul 17, 2016 at 13:02

2 Answers 2

1

The solution using isset and array_values functions:

// $arr is your initial array
$result = [];
foreach ($arr as $obj) {
    $innerObj = (object)[ 'Treatment_ID' => $obj->Treatment_ID, 'AmountAdministered' => $obj->AmountAdministered,
                          'Injectable_ID' => $obj->Injectable_ID, 'InjectableName' => $obj->InjectableName ];

    if (!isset($result[$obj->TreatmentLog_ID])) {
        $result[$obj->TreatmentLog_ID] = (object)[
            'TreatmentLog_ID' => $obj->TreatmentLog_ID,
            'DateAdministered' => $obj->DateAdministered,
            'Notes' => $obj->Notes,
            'Treatments' => [$innerObj]
        ];
    } else {
        $result[$obj->TreatmentLog_ID]->Treatments[] = $innerObj;
    }
}

$result = array_values($result);
print_r($result);  // will output the expected result
Sign up to request clarification or add additional context in comments.

Comments

0

Try this.

We use array_filter() to fetch all of the elements from the $inputArray with the same TreatmentLog_ID. Then we transform those filtered elements with array_map(). We have to create a copy of each element with clone, since they're objects and objects are passed by reference. Then we unset() the keys we don't need in the copy.

<?php

$inputArray = [
    0 => (object) [
        'TreatmentLog_ID' => 131,
        'DateAdministered' => '2016-07-15',
        'Notes' => '',
        'Treatment_ID' => 144,
        'AmountAdministered' => 1.5,
        'Injectable_ID' => 2,
        'InjectableName' => 'Baytril'
    ],

    1 => (object) [
        'TreatmentLog_ID' => 133,
        'DateAdministered' => '2016-07-12',
        'Notes' => '',
        'Treatment_ID' => 146,
        'AmountAdministered' => 1.2,
        'Injectable_ID' => 20,
        'InjectableName' => 'Vitamin C'
    ],

    2 => (object) [
        'TreatmentLog_ID' => 133,
        'DateAdministered' => '2016-07-12',
        'Notes' => '',
        'Treatment_ID' => 147,
        'AmountAdministered' => 1.3,
        'Injectable_ID' => 21,
        'InjectableName' => 'Vitamin E'
    ],
];

$transformedArray = [];
foreach ($inputArray as $key => $value)
{
    $transformedArray[$key] = [
        'TreatmentLog_ID' => $value->TreatmentLog_ID,
        'DateAdministered' => $value->DateAdministered,
        'Notes' => $value->Notes,
        'Treatments' => array_map(
            function ($v) {
                $copy = clone $v;

                unset($copy->Notes);
                unset($copy->DateAdministered);
                unset($copy->TreatmentLog_ID);

                return $copy;
            },
            array_filter($inputArray, function ($v) use ($value) {
                return $v->TreatmentLog_ID == $value->TreatmentLog_ID;
            })
        )
    ];
}

var_dump($transformedArray);

This gives me:

array(3) {
  [0]=>
  array(4) {
    ["TreatmentLog_ID"]=>
    int(131)
    ["DateAdministered"]=>
    string(10) "2016-07-15"
    ["Notes"]=>
    string(0) ""
    ["Treatments"]=>
    array(1) {
      [0]=>
      object(stdClass)#5 (4) {
        ["Treatment_ID"]=>
        int(144)
        ["AmountAdministered"]=>
        float(1.5)
        ["Injectable_ID"]=>
        int(2)
        ["InjectableName"]=>
        string(7) "Baytril"
      }
    }
  }
  [1]=>
  array(4) {
    ["TreatmentLog_ID"]=>
    int(133)
    ["DateAdministered"]=>
    string(10) "2016-07-12"
    ["Notes"]=>
    string(0) ""
    ["Treatments"]=>
    array(2) {
      [1]=>
      object(stdClass)#6 (4) {
        ["Treatment_ID"]=>
        int(146)
        ["AmountAdministered"]=>
        float(1.2)
        ["Injectable_ID"]=>
        int(20)
        ["InjectableName"]=>
        string(9) "Vitamin C"
      }
      [2]=>
      object(stdClass)#7 (4) {
        ["Treatment_ID"]=>
        int(147)
        ["AmountAdministered"]=>
        float(1.3)
        ["Injectable_ID"]=>
        int(21)
        ["InjectableName"]=>
        string(9) "Vitamin E"
      }
    }
  }
  [2]=>
  array(4) {
    ["TreatmentLog_ID"]=>
    int(133)
    ["DateAdministered"]=>
    string(10) "2016-07-12"
    ["Notes"]=>
    string(0) ""
    ["Treatments"]=>
    array(2) {
      [1]=>
      object(stdClass)#8 (4) {
        ["Treatment_ID"]=>
        int(146)
        ["AmountAdministered"]=>
        float(1.2)
        ["Injectable_ID"]=>
        int(20)
        ["InjectableName"]=>
        string(9) "Vitamin C"
      }
      [2]=>
      object(stdClass)#9 (4) {
        ["Treatment_ID"]=>
        int(147)
        ["AmountAdministered"]=>
        float(1.3)
        ["Injectable_ID"]=>
        int(21)
        ["InjectableName"]=>
        string(9) "Vitamin E"
      }
    }
  }
}

Let's break down how we build Treatments:

'Treatments' => array_map(
    function ($v) {
        $copy = clone $v;

        unset($copy->Notes);
        unset($copy->DateAdministered);
        unset($copy->TreatmentLog_ID);

        return $copy;
    },
    array_filter($inputArray, function ($v) use ($value) {
        return $v->TreatmentLog_ID == $value->TreatmentLog_ID;
    })
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.