0

I am trying to loop through an array of block components, that each can have n number of nested components (profile or avatar).

Now, what I want to do is to show these blocks x number of times, where x is the number of data from a payload array:

$payload['users'] = [
    ['name' => 'Oliver'],
    ['name' => 'John']
];

So since the above payload users length is 2, this should be rendered:

- block #1
  -- profile
  -- avatar
- block #2
  -- profile
  -- avatar

I am trying to render the above the same way by using a nested foreach loop. See the below code:

$payload['users'] = [
    ['name' => 'Oliver'],
    ['name' => 'John']
];

$schema = [
    "id" => 1,
    "name" => "Users",
    "components" => [
        [
            "key" => "0",
            "name" => "block",
            "components" => [
                [
                    "key" => "1",
                    "name" => "profile"
                ],
                [
                    "key" => "2",
                    "name" => "avatar"
                ]
            ],
        ]
    ],
];

$toPush = [];
foreach ($schema['components'] as $key => $value) {
    
        foreach ($value['components'] as $no => $component) {
                $iterator = $payload['users'];
                for ($x = 0; $x < count($iterator); $x ++) {
                    $copy = $component;
                    $copy['item'] = $iterator[$x];
                    $copy['key'] = $copy['key'] . '-' . $x;
                    $toPush[] = $copy;
                }
            $schema['components'][$key]['components'] = $toPush;
        }
}

print_r($toPush);

The problem is that the above prints it out like this:

- block #1
  -- profile
  -- profile
- block #2
  -- avatar
  -- avatar

I have created an 3v4l of this, which can be found here.

How can I achieve my desired scenario?

For reference I am using the Laravel framework.

Desired output

Also available as an 3v4l here.

[
    "components" => [
        [
            "key" => "1",
            "name" => "profile",
            "item" => [
                "name" => "Oliver"
            ]
        ],
        [
            "key" => "2",
            "name" => "avatar",
            "item" => [
                "name" => "Oliver"
            ]
        ],
        [
            "key" => "3",
            "name" => "profile",
            "item" => [
                "name" => "John"
            ]
        ],
        [
            "key" => "4",
            "name" => "avatar",
            "item" => [
                "name" => "John"
            ]
        ]
    ],
];
5
  • what part of that original data is 'profile' or 'avatar'? i dont understand how these sample outputs relate to this 'schema' Commented Jan 4, 2021 at 10:38
  • The original data (payload.users) is custom data, that my users can specify. What I want to do, is that for the count of payload.users, I want to render the nested components under components.name = block. But they should be rendered "pair-wise" and not sequentially. Commented Jan 4, 2021 at 10:40
  • put up the actual output you want based on this payload Commented Jan 4, 2021 at 10:49
  • @lagbox I have edited my OP with the desired output of the nested components. Commented Jan 4, 2021 at 10:55
  • you need to swap your inner loops, you need to iterate the users payload then in that loop iterate the schema components Commented Jan 4, 2021 at 11:14

1 Answer 1

1

This logic may be of some help to you.

$toPush = [];
$count = 0;
foreach ($schema['components'] as $value) {
    foreach ($value['components'] as $key => $component) {
        foreach ($payload['users'] as $idx => $user) {
            $toPush['components'][$count]['key'] = $count;
            $toPush['components'][$count]['name'] = $value['components'][$idx]['name'];
            $toPush['components'][$count]['item'] = $payload['users'][$key];
            $count++;
        }
    }
}

demo

Sign up to request clarification or add additional context in comments.

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.