Reputation: 2157
I have a list of stores and they can have multiple categories.
Today i display each store multiple times, one line with only one category.
How can i group the stores, creating an array of their categories, so the store is displayed only one time and have their multiple categories ?
This is my attempt:
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
array_push(
$stores,
[
"id"=> $row["id"],
"name"=> $row["nome"],
"categories"=> array([
"name"=> $row["categories"]
//how can i have an array of categories
])
]
);
}
This is how i display the json result:
{
id: 74,
name: "First Store",
categories: [
{
name: "Clothes"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Food"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Toys"
}
]
},
This is how i need to show the Json:
{
id: 74,
name: "First Store",
categories: [
{
name: "Clothes"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Food"
},
{
name: "Toys"
}
]
},
In my attempt i try inside the while to create the categories but have a php warning: end() expects parameter 1 to be array, null given
if( isset($stores) ) {
if( end($stores['id']) != $row["id"] ) {
array_push($category_array, $row["categories"]);
}
}
Upvotes: 1
Views: 204
Reputation: 2832
I believe you are looking for something like this when processing your returned MySQL
rows to json_encode
: https://3v4l.org/d4Wf2
This will place the stores in 1 temp $storeTracker array
with the store id as the array key
(this assumes store id is a constant in each record you're getting back and is always the same). From here you can then check if the array key
(store id) already exists, and if so, continue to add categories to the store if the category doesn't already exist. After doing this, you can then parse to json_encode
to create a valid JSON
object to return. Granted there may be a more eloquent way to achieve this, but this showcases the array
manipulation and whatnot to try and group data for your case.
<?php
// Data coming from MySQL Database
$rowData = [];
$rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'Food'];
$rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'DVDs'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Food'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Clothing'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
/**
* Check if store category name already added to store record
*/
function categoryExistsAlready($categories, $category) {
foreach($categories as $key => $catArr) {
if(strtolower($catArr['name']) === strtolower($category)) {
return true;
}
}
return false;
}
$storeTracker = [];
foreach($rowData as $key => $storeData) {
$storeCategory = $storeData['categories'];
$storeId = $storeData['id'];
// If store exists, add category to categories array
if (array_key_exists($storeId, $storeTracker)) {
if (!categoryExistsAlready($storeTracker[$storeId]['categories'], $storeCategory)) {
$storeTracker[$storeId]['categories'][] = ['name' => $storeCategory];
}
continue;
}
// Update store categories to be array with category
$storeData['categories'] = [];
$storeData['categories'][] = ['name' => $storeCategory];
// Add store data to overall tracking array
$storeTracker[$storeId] = $storeData;
}
// Format JSON response
$jsonReturn = '[';
$i = count($storeTracker);
foreach($storeTracker as $storeId => $storeData) {
$i--;
$jsonReturn .= json_encode($storeData);
// Determine last comma separating objects
if ($i > 0) {
$jsonReturn .= ',';
}
}
$jsonReturn .= ']';
echo $jsonReturn;
Will give you this valid JSON
https://jsonlint.com/:
[{
"id": 74,
"name": "First Store",
"categories": [{
"name": "Food"
}, {
"name": "DVDs"
}]
}, {
"id": 1,
"name": "Second Store",
"categories": [{
"name": "Food"
}, {
"name": "Toys"
}, {
"name": "Clothing"
}]
}, {
"id": 3,
"name": "Third Store",
"categories": [{
"name": "Toys"
}, {
"name": "Clothing"
}]
}]
Upvotes: 1