简体   繁体   中英

PHP loop and rebuild array grouped by value (topic) output JSON

I have this result from MYSQL; the content_groups are returned from MYSQL ordered by TopicId already.

Array
(
    [0] => Array
        (
            [ContentGroupId] => 1
            [TopicId] => 1
            [TopicName] => Meditations
            [ContentGroupName] => Guided Meditations 1
        )

    [1] => Array
        (
            [ContentGroupId] => 2
            [TopicId] => 1
            [TopicName] => Meditations
            [ContentGroupName] => Guided Meditations 2
        )

    [2] => Array
        (
            [ContentGroupId] => 3
            [TopicId] => 1
            [TopicName] => Meditations
            [ContentGroupName] => Guided Meditations 3
        )

    [3] => Array
        (
            [ContentGroupId] => 4
            [TopicId] => 2
            [TopicName] => Hypnosis
            [ContentGroupName] => Hypnosis Programs 1
        )

    [4] => Array
        (
            [ContentGroupId] => 5
            [TopicId] => 2
            [TopicName] => Hypnosis
            [ContentGroupName] => Hypnosis Programs 2
        )

    [5] => Array
        (
            [ContentGroupId] => 6
            [TopicId] => 3
            [TopicName] => Mindfulness
            [ContentGroupName] => Mindfulness Guides 1
        )

    [6] => Array
        (
            [ContentGroupId] => 7
            [TopicId] => 3
            [TopicName] => Mindfulness
            [ContentGroupName] => Mindfulness Guides 2
        )

    [7] => Array
        (
            [ContentGroupId] => 8
            [TopicId] => 3
            [TopicName] => Mindfulness
            [ContentGroupName] => Mindfulness Guides 3
        )

I'm trying to loop through this so I can group by topic and JSON encode to look like this:

topics: [
    {
      TopicId: 1,
      TopicName: Mediations,
      content_groups: [
        {
           ContentGroupId: 1,
           TopicId: 1,
           TopicName: "Mediations",
           ContentGroupName: "Guided Meditations 1"
        },
        {
           ContentGroupId: 2,
           TopicId: 1,
           TopicName: "Mediations",
           ContentGroupName: "Guided Meditations 2"
        },
        {
           ContentGroupId: 3,
           TopicId: 1,
           TopicName: "Mediations",
           ContentGroupName: "Guided Meditations 3"
        }
      ]
    },
    {
      TopicId: 2,
      TopicName: Hypnosis,
      content_groups: [
        {
           ContentGroupId: 4,
           TopicId: 2,
           TopicName: "Hypnosis",
           ContentGroupName: "Hypnosis Programs 1"
        },
        {
           ContentGroupId: 5,
           TopicId: 2,
           TopicName: "Hypnosis",
           ContentGroupName: "Hypnosis Programs 2"
        }
      ]
    },
    {
      TopicId: 3,
      TopicName: Mindfulness,
      content_groups: [
        {
           ContentGroupId: 6,
           TopicId: 3,
           TopicName: "Hypnosis",
           ContentGroupName: "Mindfulness Guides 1"
        },
        {
           ContentGroupId: 7,
           TopicId: 3,
           TopicName: "Hypnosis",
           ContentGroupName: "Mindfulness Guides 2"
        },
        {
           ContentGroupId: 8,
           TopicId: 3,
           TopicName: "Hypnosis",
           ContentGroupName: "Mindfulness Guides 3"
        }
      ]
    }
 ]

I originally just did a separate MYSQL call as I looped through each topic to get the corresponding content groups, but as topics grows, this seems inefficient as I could more easily just make one SQL call to get all needed content groups then rebuild the array to group by the corresponding topic, but I'm struggling to figure out how to output that to get the desired final result.

Using TopicId as a temporary associative key, isset() can be used to efficiently determine if you are processing data for a new group or if the appropriate group already exists.

Code: ( Demo )

$array = [
    ['ContentGroupId' => 1, 'TopicId' = >1, 'TopicName' => 'Meditations', 'ContentGroupName' => 'Guided Meditations 1'],
    ['ContentGroupId' => 2, 'TopicId' => 1, 'TopicName' => 'Meditations', 'ContentGroupName' => 'Guided Meditations 2'],
    ['ContentGroupId' => 3, 'TopicId' = >1, 'TopicName' => 'Meditations', 'ContentGroupName' => 'Guided Meditations 3'],
    ['ContentGroupId' => 4, 'TopicId' => 2, 'TopicName' => 'Hypnosis', 'ContentGroupName' => 'Hypnosis Programs 1'],
    ['ContentGroupId' => 5, 'TopicId' => 2, 'TopicName' => 'Hypnosis', 'ContentGroupName' => 'Hypnosis Programs 2'],
    ['ContentGroupId' => 6, 'TopicId' => 3, 'TopicName' => 'Mindfulness', 'ContentGroupName' => 'Mindfulness Guides 1'],
    ['ContentGroupId' => 7, 'TopicId' => 3, 'TopicName' => 'Mindfulness', 'ContentGroupName' => 'Mindfulness Guides 2'],
    ['ContentGroupId' => 8, 'TopicId' => 3, 'TopicName' => 'Mindfulness', 'ContentGroupName' => 'Mindfulness Guides 3']
];
foreach ($array as $a) {
    if (!isset($grouped[$a['TopicId']])) {
        $grouped[$a['TopicId']] = array_slice($a, 1, 2);  // write TopicID & TopicName just once to group
    }
    $grouped[$a['TopicId']]['content_groups'][] = $a;   // write all elements to content_groups
}
$grouped=['topics' => array_values($grouped)];  // re-index temp keys and nest inside topics element
var_export(json_encode($grouped));

Output:

'{"topics":[{"TopicId":1,"TopicName":"Meditations","content_groups":[{"ContentGroupId":1,"TopicId":1,"TopicName":"Meditations","ContentGroupName":"Guided Meditations 1"},{"ContentGroupId":2,"TopicId":1,"TopicName":"Meditations","ContentGroupName":"Guided Meditations 2"},{"ContentGroupId":3,"TopicId":1,"TopicName":"Meditations","ContentGroupName":"Guided Meditations 3"}]},{"TopicId":2,"TopicName":"Hypnosis","content_groups":[{"ContentGroupId":4,"TopicId":2,"TopicName":"Hypnosis","ContentGroupName":"Hypnosis Programs 1"},{"ContentGroupId":5,"TopicId":2,"TopicName":"Hypnosis","ContentGroupName":"Hypnosis Programs 2"}]},{"TopicId":3,"TopicName":"Mindfulness","content_groups":[{"ContentGroupId":6,"TopicId":3,"TopicName":"Mindfulness","ContentGroupName":"Mindfulness Guides 1"},{"ContentGroupId":7,"TopicId":3,"TopicName":"Mindfulness","ContentGroupName":"Mindfulness Guides 2"},{"ContentGroupId":8,"TopicId":3,"TopicName":"Mindfulness","ContentGroupName":"Mindfulness Guides 3"}]}]}'

While looping through MySQL query result create array then use json_encode for that array

$query= mysqli_query("SELECT ...");
$rows = array();
while($result = mysqli_fetch_assoc($query)) {
$rows[] = $result;
}
print json_encode($rows);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM