1

From sql I create an array $sails that look like:

Array
(
    [0] => Array
        (
            [type] => RES
            [date] => 2022-05-14
            [doy] => 133
            [skipperid] => 217
            [boat] => Laura
            [start] => 09:00:00
            [end] => 22:00:00
            [spots] => 5
            [fname] => David
            [lname] => Cross
        )

    [1] => Array
        (
            [type] => SAIL
            [date] => 2022-05-14
            [doy] => 133
            [skipperid] => 1
            [boat] => Avrora
            [start] => 10:00:00
            [end] => 13:00:00
            [spots] => 3
            [fname] => Bob
            [lname] => Smith
        )

    [2] => Array
        (
            [type] => RES
            [date] => 2022-05-24
            [doy] => 143
            [skipperid] => 1
            [boat] => Irlbach
            [start] => 09:00:00
            [end] => 13:30:00
            [spots] => 3
            [fname] => Bob
            [lname] => Smith
        )

)

I want to convert this to an object of arrays of objects. Essentially something that looks like

{[{},{}],[{}]}

Here's what I am trying:

$allSails =  new stdClass();    
$sailCnt = count($sails);

for($i = 0; $i < $sailCnt; $i++){    
    $dayKey = $sails[$i]['doy']; 
    $allSails->$dayKey = array();

    $itmCnt = count($sails[$i]);    
    $keys = array_keys($sails[$i]);    
    $items = new stdClass();   
    $j = 0;

    foreach($keys as $key){    
        $items->$key = $sails[$i][$keys[$j]];    
        $j++;    
    }
    array_push($allSails->$dayKey, clone $items);    
}

but this is the output:

stdClass Object
(
    [133] => Array
        (
            [0] => stdClass Object
                (
                    [type] => SAIL
                    [date] => 2022-05-14
                    [doy] => 133
                    [skipperid] => 1
                    [boat] => Avrora
                    [start] => 10:00:00
                    [end] => 13:00:00
                    [spots] => 3
                    [fname] => Bob
                    [lname] => Smith
                )
        )
    [143] => Array
        (
            [0] => stdClass Object
                (
                    [type] => RES
                    [date] => 2022-05-24
                    [doy] => 143
                    [skipperid] => 1
                    [boat] => Irlbach
                    [start] => 09:00:00
                    [end] => 13:30:00
                    [spots] => 3
                    [fname] => Bob
                    [lname] => Smith
                )
        )
)
4
  • You can easily convert an array to an object like this: $items = (object) $sails[$i]; Commented Jan 27, 2022 at 20:30
  • Also, to loop an array you can just do foreach($sails[$i] as $sail) {...}, and if you need the key do foreach($sails[$i] as $key => $sail) {...} Commented Jan 27, 2022 at 20:33
  • Lastly, to explain why it wasn't working as you expected, the issue wasn't array_push but this portion of code: $allSails->$dayKey = array();. It was always setting the key to an empty array and you need to do it just once (like in the various solutions given, first check if it doesn't exist, create the empty array, if it already exist just add more elements to it). Commented Jan 27, 2022 at 20:41
  • @Gonzalingui yep, you nailed it. Thanks for the help Commented Jan 27, 2022 at 20:49

3 Answers 3

2

This is a clean-up of the OP's code:

$sails = [
    ['type' => 'RES', 'date' => '2022-05-14', 'doy'  => '133', 'skipperid' => '217', 'boat' => 'Laura', 'start' => '09:00:00', 'end'  => '22:00:00', 'spots'  => '5', 'fname'  => 'David', 'lname'  => 'Cross'],
    ['type' => 'SAIL', 'date' => '2022-05-14', 'doy'  => '133', 'skipperid' => '1', 'boat' => 'Avrora', 'start'  => '10:00:00', 'end'  => '13:00:00', 'spots'  => '3', 'fname'  => 'Bob', 'lname'  => 'Smith',],
    ['type' => 'RES', 'date' => '2022-05-24', 'doy'  => '143', 'skipperid' => '1', 'boat' => 'Irlbach', 'start'  => '09:00:00', 'end'  => '13:30:00', 'spots'  => '3', 'fname'  => 'Bob', 'lname'  => 'Smith',],
];

$allSails = new stdClass();

foreach($sails as $sail) {
  $dayKey = $sail['doy'];
  if (!array_key_exists($dayKey, (array)$allSails)) {
    $allSails->{$dayKey} = [];
  }
  $items = new stdClass();
  foreach ($sail as $key => $value) {
    $items->{$key} = $value;
  }
  $allSails->$dayKey[] = $items;
}

print_r($allSails);
Sign up to request clarification or add additional context in comments.

4 Comments

makes sense but it didn't work
I just added the $sails array. With that I get the desired output here.
do you have a reference for $obj->$key[] I haven't seen that before. why does adding [] make it add sequentially and without it override what's there?
php.net/manual/en/function.array-push.php. The second note says: If you use array_push() to add one element to the array, it's better to use $array[] = because in that way there is no overhead of calling a function.
1
$data = [
    ['type' => 'RES', 'date' => '2022-05-14', 'doy'  => '133', 'skipperid' => '217', 'boat' => 'Laura', 'start' => '09:00:00', 'end'  => '22:00:00', 'spots'  => '5', 'fname'  => 'David', 'lname'  => 'Cross'],
    ['type' => 'SAIL', 'date' => '2022-05-14', 'doy'  => '133', 'skipperid' => '1', 'boat' => 'Avrora', 'start'  => '10:00:00', 'end'  => '13:00:00', 'spots'  => '3', 'fname'  => 'Bob', 'lname'  => 'Smith',],
    ['type' => 'RES', 'date' => '2022-05-24', 'doy'  => '143', 'skipperid' => '1', 'boat' => 'Irlbach', 'start'  => '09:00:00', 'end'  => '13:30:00', 'spots'  => '3', 'fname'  => 'Bob', 'lname'  => 'Smith',],
];

$result = [];

array_walk($data, function ($item) use (&$result) {
  $obj = new stdClass();
  foreach ($item as $key => $value) {
    $obj->{$key} = $value;
  }
  $result[$obj->doy][] = $obj;
});

print_r($result);

If you really want to put these into a wrapper object instead of an array amend it to look like this:

$result = new stdClass();   // Changed this line

array_walk($data, function ($item) use (&$result) {
  $obj = new stdClass();
  foreach ($item as $key => $value) {
    $obj->{$key} = $value;
  }
  $result->{$obj->doy}[] = $obj;   // Changed this line
});

6 Comments

thanks but this doesn't explain why my code isn't working.
$result->$dayKey = []; is the problem in your code.
How do you fix it?
Only assign [] if $result->$dayKey does not exist.
$daykey always exists. This makes no sense
|
0

Have you tried doing simple casting?

$object=(object) $sails

If that does not work, you can use a JSON shortcut:

$json=json_encode($sails, JSON_FORCE_OBJECT)
$object=json_decode($json, false)

2 Comments

not a clue on how to try this. On what?
Clearly on your array $sails.

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.