Built a multidimensional array with PHP from an SQL query - php

Form a SQL query i receive the following datas from two differences tables.
|----------------|----------|--------------|
|CON_ContinentId | FRU_Name | FRU_Quantity |
|----------------|----------|--------------|
| 1 | Apple | 100 |
| 1 | Banana | 200 |
| 2 | Peach | 300 |
| 2 | Cherry | 400 |
| 3 | Coconut | 500 |
| 4 | Grape | 1100 |
| 5 | Pear | 1500 |
|----------------|----------|--------------|
I need to get an array like this:
$datas = [
1 => [
[
'FRU_Name' => 'Apple',
'FRU_Quantity' => '100'
],
[
'FRU_Name' => 'Banana',
'FRU_Quantity' => '200'
]
],
2 => [
[
'FRU_Name' => 'Peach',
'FRU_Quantity' => '300'
],
[
'FRU_Name' => 'Cherry',
'FRU_Quantity' => '400'
]
],
3 => [
[
'FRU_Name' => 'Coconut',
'FRU_Quantity' => '500'
]
],
4 => [
[
'FRU_Name' => 'Grape',
'FRU_Quantity' => '1000'
]
],
5 => [
[
'FRU_Name' => 'Pear',
'FRU_Quantity' => '1100'
]
],
]
So, basically, I need to groupe the rows with the same CON_ContinentId and list the FRU_Name and FRU_Quantity.
What I try:
$datas = [];
while ($fetch = $query->fetch(PDO::FETCH_ASSOC)){
$CON_ContinentId = $fetch['CON_ContinentId'];
$FRU_Name = $fetch['FRU_Name'];
$FRU_Quantity = $fetch['FRU_Quantity'];
if (!in_array($CON_ContinentId, $datas)) {
$datas = array(
'CON_ContinentId' => $CON_ContinentId,
'FRU_Name' => $FRU_Name,
'FRU_Quantity' => $FRU_Quantity
);
}
}
But it doesn't work.
Could you please help me ?
Thanks.

There are a few different problems in your code:
Your desired array structure isn't valid, so it's unclear what you want.
$datas isn't initialized. Use $datas = [] instead.
$FRU_Name is being set twice? Did you mean $FRU_Quantity?
This code won't group multiple fruits under their continent ID--it'll put them into an associative array alongside their continent ID.

Every iteration of your results set, just use the CON_ContinentID value as the key, then [] to auto-index the subarrays.
There is no need to declare resultset values to new variables, just apply them to the $datas declaration and move on.
while ($fetch = $query->fetch(PDO::FETCH_ASSOC)){
$datas[$fetch['CON_ContinentId']][]=['FRU_Name'=>$fetch['FRU_Name'],'FRU_Quantity' =>$fetch['FRU_Quantity']];
}
a bit more explanation...
// hard-coded keys -vvvvvvvv-----------------------vvvvvvvvvvvv
$datas[$fetch['CON_ContinentId']][]=['FRU_Name'=>$fetch['FRU_Name'],'FRU_Quantity' =>$fetch['FRU_Quantity']];
// id-^^^^^^^^^^^^^^^^^^^^^^^^^ ^^-auto-index ^^^^^^^^^^^^^^^^^^------------------^^^^^^^^^^^^^^^^^^^^^^-resultset data
// ^^^^^^^^^^-keys start from zero, and increment by one at each new pushed subarray)

Related

Creating nested json for hotel system

I want to create a nested json that comes with post.
I have 3 fields. Adults, children and baby. But, there are also dates for children and baby areas. For example; Children 1 Birthday, Children 2 Birthday, Baby 1 Birthday, Baby 2 Birthday
When I try with the code below, I can't print child dates by room. Writes in bulk. How can I POST with php like json below?
+---------+----------+-------+
| Adults | Children | Baby | (select box field)
+--------------------+--------
| 1 | 0 | 0 |
+--------------------+--------
| 2 | 1 | 1 | (also available for children and baby areas)
+--------------------+-------+
| 3 | 2 | 2 |
+---------+----------+-------+
rooms: [
{
adults: 2,
child: [
child_total: 1
child_date: [
"2017-08-10"
],
],
baby: [
baby_total: 1
baby_date: [
"2017-07-01"
],
],
},
{
adults: 1,
child: [
child_total: 2
child_date: [
"2017-08-08",
"2017-08-09"
],
],
baby: [
baby_total: 2
baby_date: [
"2017-06-08",
"2017-05-09"
],
],
}
],
foreach ($this->input->post('adults') as $key => $value) {
foreach ($_POST['child_total'] as $value2) {
$child_date = [];
foreach ($_POST['child_date'] as $key2 => $value3) {
$child_date[] = $value3;
}
}
$rooms[] = array(
'adults' => $_POST['adults'][$key],
'child' => array(
'child_total' => $_POST['child_total'][$key],
'child_date' => $child_date
)
);
}
print json_encode($rooms, JSON_PRETTY_PRINT);

Laravel Eloquent Nested Group by its Relation

Please help me how to add another nested group by based on game category relation. I have 3 tables related using laravel 5.4 eloquent.
Game Providers Table
+----+-------------+--------------+------------------+
| id | game_name | game_type_id | game_category_id |
+----+-------------+--------------+------------------+
| 1 | Sample | 1 | 1 |
| 1 | Sample 0 | 1 | 2 |
| 2 | Sample 1 | 2 | 1 |
| 3 | Sample 2 | 2 | 2 |
+----+-------------+--------------+------------------+
Game Types
+----+-------------+
| id | name |
+----+-------------+
| 1 | Chess |
| 2 | Poker |
+----+-------------+
Game Categories
+----+-------------+
| id | name |
+----+-------------+
| 1 | Recommended |
| 2 | Optional |
+----+-------------+
I'm done of for first nested for game type relation but i dont know how to add another group by for game categories
$game_providers = GameProvider::all();
$game_providers = $game_providers->groupBy(function ($game_provider) {
return $game_provider->game_type->name;
})->all();
and its output
Array{
'Chess' => Array{
0 => Array{
'id' => 1,
'game_name' => 'Sample',
'game_type_id' => 1,
'game_category_id' => 2
},
1 => Array{
'id' => 2,
'game_name' => 'Sample 0',
'game_type_id' => 1,
'game_category_id' => 2
},
},
'Poker' => Array{
0 => Array{
'id' => 3,
'game_name' => 'Sample 1',
'game_type_id' => 2,
'game_category_id' => 1
},
1 => Array{
'id' => 4,
'game_name' => 'Sample 2',
'game_type_id' => 2,
'game_category_id' => 2
},
},
}
My expected output
Array{
'Chess' => Array{
'Recommended' => Array{
0 => Array{
'id' => 1,
'game_name' => 'Sample',
'game_type_id' => 1,
'game_category_id' => 2
}
},
'Optional' => Array{
0 => Array{
'id' => 2,
'game_name' => 'Sample 0',
'game_type_id' => 1,
'game_category_id' => 2
}
}
},
'Poker' => Array{
'Recommended' => Array{
0 => Array{
'id' => 3,
'game_name' => 'Sample 1',
'game_type_id' => 2,
'game_category_id' => 1
}
},
'Optional' => Array{
0 => Array{
'id' => 4,
'game_name' => 'Sample 2',
'game_type_id' => 2,
'game_category_id' => 2
}
}
}
}
With L5, one way of acieving this can be:
GameProvider::with('game_categories.game_types')
->get()
->groupBy([
'gameTypes.name',
'gameCategories.name'
]);
Should be something along the lines of :
GameProvider::with('game_categories.game_types')->get()->map(function ($game) {
return $game->game_categories->groupBy('name')->map(function ($catGame) {
return $catGame->map(function ($category) {
return $category->game_types->groupBy('name');
});
});
});

Converting a flat array to a specific array format

Fellow PHP programmers, consider the following DB result:
+---------+-----------+---------------+--------+
| node_id | parent_id | path | branch |
+---------+-----------+---------------+--------+
| 1 | 0 | /1/ | NULL |
| 2 | 1 | /1/2/ | NULL |
| 3 | 2 | /1/2/3/ | 1 |
| 4 | 3 | /1/2/3/4/ | 1 |
| 8 | 4 | /1/2/3/4/8/ | 1 |
| 9 | 8 | /1/2/3/4/8/9/ | 1 |
| 7 | 4 | /1/2/3/4/7/ | 0 |
| 5 | 2 | /1/2/5/ | 0 |
| 6 | 5 | /1/2/5/6/ | 0 |
+---------+-----------+---------------+--------+
How does one get the following PHP array:
[
[
'id' => 1,
'parentId' => 0,
],
[
'id' => 2,
'parentId' => 1,
'nodes' => [
[ // when branch == 0
[
'id' => 5,
'parentId' => 2
],
[
'id' => 6,
'parentId' => 5
],
],
[ // when branch == 1
[
'id' => 3,
'parentId' => 2
],
[
'id' => 4,
'parentId' => 3,
'nodes' => [
[ // when branch == 0
[
'id' => 7,
'parentId' => 4
],
],
[ // when branch == 1
[
'id' => 8,
'parentId' => 4
],
[
'id' => 9,
'parentId' => 8
],
]
]
],
]
]
]
]
The function should work with unlimited depth.
Any help would be greatly appreciated as I've been hitting a wall.
Something like this:
function buildTree($arr, $parentID)
{
$children = [];
foreach ($arr as $item) {
if ($item['parent_id'] == $parentID) {
array_push($children, [
'id' => $item['node_id'],
'parentId' => $item['parent_id'],
'nodes' => buildTree($arr, $item['node_id'])
]);
}
}
return $children;
}
$tree = buildTree($flat, null);
UPD:
function getBranches($arr, $parentID)
{
$branches = array();
foreach ($arr as $item) {
if ($item['parent_id'] == $parentID) {
$bKey = $item['branch'];
$node = array(
'id' => $item['node_id'],
'parentId' => $item['parent_id']
);
$firstNodeChild = false;
if ($nodeChildren = getBranches($arr, $item['node_id'])) {
$hasKey = array_key_exists($bKey, $nodeChildren);
if ($hasKey && $nodeChildren[$bKey]) {
if (sizeof($nodeChildren[$bKey]) == 1) {
$firstNodeChild = $nodeChildren[$bKey][0];
unset($nodeChildren[$bKey]);
}
}
if ($nodeChildren) {
$node['nodes'] = $nodeChildren;
}
}
if (!array_key_exists($bKey, $branches)) {
$branches[$bKey] = array();
}
$branches[$bKey][] = $node;
if (false !== $firstNodeChild) {
$branches[$bKey][] = $firstNodeChild;
}
}
}
ksort($branches);
return $branches;
}
$tree = getBranches($arr, 0);

Yii2 GridView multidimensional array

I got array:
123 => [
"2015-09-01" => ["sum"=>"1030","count"=>"4"],
"2015-09-02" => ["sum"=>"10","count"=>"24"],
"2015-09-03" => ["sum"=>"120","count"=>"34"],
"2015-09-04" => ["sum"=>"200","count"=>"45"]
],
124 => [
"2015-09-01" => ["sum"=>"132","count"=>"48"],
"2015-09-02" => ["sum"=>"10","count"=>"24"],
"2015-09-03" => ["sum"=>"120","count"=>"34"],
"2015-09-04" => ["sum"=>"200","count"=>"45"]
],
Now i like display this in GridView to get table like this:
--------------------------------------------
| ID | 2015-09-01 | 2015-09-02 | 2015-09-03|
| |-------------------------------------|
| | sum |count| sum |count | sum |count|
|------------------------------------------|
|123 |1030 | 4 | 10 | 24 |120 | 34 |
|------------------------------------------|
|124 |132 | 48 | 10 | 24 |120 | 34 |
--------------------------------------------
Question how to get such an effect ?
For a 2d array with numbered rows, each row containing an array of elements, the following implementation is quite trivial.
1. Initialize the data provider
First initialize the array data provider in your controller by passing the data in allModels parameter. mode details of ArrayDataProvider can be found here
$dataProvider = new ArrayDataProvider([
'allModels'=> $your2darray,
'pagination' => [
'pageSize' => 10,
],
]);
2. Display the Grid
Assuming you have passed the above data provider variable, in your view , use it in the grid as below, specifying whatever column to be displayed.
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'field1',
...
['class' => 'yii\grid\ActionColumn'],
],
]); ?>

MySQL entries with self parent_id into sorted cascade array

I need help with an application I'm creating.
I have a table, looks kind like this:
+----+-----------+---------+
| id | parent_id | name |
+----+-----------+---------+
| 1 | null | test |
+----+-----------+---------+
| 2 | null | test2 |
+----+-----------+---------+
| 4 | 1 | test3 |
+----+-----------+---------+
| 5 | 2 | test4 |
+----+-----------+---------+
And now, I get all the data in one array. I would like to get kinda this structure (php array as an cascade):
array(
0 => array(
'id' => 1,
'parent_id' => null,
'name' => 'test',
'children' => array(
'id' => 4,
'parent_id' => 1,
'name' => 'test3'
)
),
1 => array(
'id' => 2,
'parent_id' => null,
'name' => 'test2',
'children' => array(
'id' => 5,
'parent_id' => 2,
'name' => 'test4'
)
)
)
So there will every entry with a "parent_id=null" be a parent, and every entry with an id in "parent_id" will be in a child array.
I started it like this:
$newArray = array();
foreach($names as $name) {
if($name['parent_id'] == null || $name['parent_id'] == 0) {
// entry is parent
$newArray[$name['id']] = $name['name'];
} else {
// entry is child
}
}
But here is also my end, I don't know how to do that. I think i have to use some kind of recursive loop function, but I don't know how to start.
Would be awesome if somebody could help me.
Kind regards,
Matt.
You can use a recursive function like this (I only added the code which is relevant for understanding):
function get_children($parentId) {
$array = array();
//Load/Find $children
foreach($children as $child) {
$array[] = array(
'id' => $child->id,
'name' => 'YourName',
'children' => get_children($child->id)
);
}
return $array;
}
If you save the data in such an array, it isn't necessary to save the parent_id, because you can get it by searching for the parent elements id.

Categories