-5

My input data is an array of objects. I need to restructure these objects so that an object with value = 0 becomes a "parent" object with a subarray which will collect all subsequent objects until another "parent" object is encountered.

Sample array:

    $array = [
        (object) ['id'=> 1, 'value' => 0],
        (object) ['id'=> 2, 'value' => 10],
        (object) ['id'=> 3, 'value' => 14],
        (object) ['id'=> 4, 'value' => 0],
        (object) ['id'=> 5, 'value' => 21],
        (object) ['id'=> 6, 'value' => 44],
    ];

The desired result:

    [
        (object) [
            'id' => 1,
            'value' => 0,
            'values' => [
                (object) ['id' => 2, 'value' => 10],
                (object) ['id' => 3, 'value' => 14],
            ],
        ],
        (object) [
            'id' => 4,
            'value' => 0,
            'values' => [
                (object) ['id' => 5, 'value' => 21],
                (object) ['id' => 6, 'value' => 44],
            ]
        ]
    ]

I'm struggling to make a start. Should I approach this with a foreach?

foreach ($array as $item) {
    // What to do?
}

Mark_
  • 113
  • 1
  • 12
  • 2
    *"// What to do?"* - For starters, please don't post your code as images. Images are static, text can be copy/pasted, which is especially helpful for this kind of question. Also, have you tried anything in your `foreach()` loop? I would think you can look at `$item->value`, and if it's `0`, push `$item` to a new array with a `->values = []` property. If it is not `0`, push it to the `->values` property of the most recent entry in your new array, etc. But yeah; first thing is [edit you question](https://stackoverflow.com/posts/73478075/edit) and post your code as text. – Tim Lewis Aug 24 '22 at 18:35

2 Answers2

0

not really sure the purpose of this exercise but this gets your desired result with the given data

$objects = [
    (object) ['id'=> 1, 'value' => 0],
    (object) ['id'=> 2, 'value' => 10],
    (object) ['id'=> 3, 'value' => 14],
    (object) ['id'=> 4, 'value' => 0],
    (object) ['id'=> 5, 'value' => 21],
    (object) ['id'=> 6, 'value' => 44],
];

$data = [];
foreach($objects as $object) {
    if ($object->value === 0) {
        $data[] = $object;
        continue;
    }

    $current = end($data);

    if (!isset($current->values)) {
        $current->values = [];
    }

    $current->values[] = $object;
}
RawSlugs
  • 520
  • 4
  • 11
0

This task is an excellent candidate for pushing data into a reference variable which has already been pushed into the result array.

By declaring the parent's subarray as a reference, you don't need to track where the parent exists in the result array.

Code: (Demo)

$result = [];
foreach ($array as $obj) {
    if (!$obj->value) {
        unset($ref);
        $obj->values = [];
        $ref = &$obj->values;
        $result[] = $obj;
        continue;
    }
    $ref[] = $obj;
}
var_export($result);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136