Remove dynamic keys from array - php

I have mysqli query that I fetch and the code below turns results into array, but I get unwanted dynamic keys 1 ,2, 3 etc. my question is it possible to remove them or do it somehow differently?
if($num > 0) {
$quest_arr['error'] = 'false';
$quest_arr['message'] = 'Success';
$quest_arr['data'] = array();
$questions = [];
foreach ($result as $r) {
if (!isset($questions[$r['QuestionId']])) {
$questions[$r['QuestionId']] = [ 'QuestionId' => $r['QuestionId'],
'question' => $r['QuestionName'],
'answers'=> []
];
}
$questions[$r['QuestionId']]['answers'][] = $r['AnswerID'];
}
array_push($quest_arr['data'], $questions);
echo json_encode($quest_arr, JSON_NUMERIC_CHECK);
} else {
echo json_encode(
array('error' => 'true','message' => 'Error')
);
}
Creates this array
{
"error": "false",
"message": "Success",
"data": [
{
"1": {
"QuestionId": 1,
"question": "Question 1",
"answers": [
1,
2,
3
]
},
"2": {
"QuestionId": 2,
"question": "Question 2",
"answers": [
null
]
},
"3": {
"QuestionId": 3,
"question": "Question 3",
"answers": [
null
]
},
}
]
}
Is it possible to remove the dynamic keys "1", "2" ,"3" ?
I would love to have json like this
{
"error": "false",
"message": "Success",
"data": [
{
"QuestionId": 1,
"question": "Question 1",
"answers": [
1,
2,
3
]
},
{
"QuestionId": 2,
"question": "Question 2",
"answers": [
null
]
},
{
"QuestionId": 3,
"question": "Question 3",
"answers": [
null
]
},
]
}

Not tested, but maybe this can work:
// instead of
// array_push($quest_arr['data'], $questions);
$questions = array_values($questions);
$quest_arr['data'] = $questions;

Related

merge all arrays with same title [duplicate]

This question already has answers here:
How to group subarrays by a column value?
(20 answers)
PHP - Group Array by its Sub Array Value (Indexed Array)
(1 answer)
Closed 6 months ago.
i have this array in php json.
i have made it to sort array by first Characther.
but now i'm stuck on how to merge the data under the same title.
my response now is.
[
{
"title": "A",
"data": {
"id": "317",
"name": "Aesethetica"
}
},
{
"title": "A",
"data": {
"id": "318",
"name": "Astonos"
}
},
{
"title": "B",
"data": {
"id": "320",
"name": "Bourjois"
}
},
{
"title": "B",
"data": {
"id": "321",
"name": "Bioderma"
}
}
]
i need to merge all data under each same title.
something like this:
[
{
"title": "A",
"data": [
{
"id": "317",
"name": "Aesethetica"
},
{
"id": "318",
"name": "Astonos"
}
]
},
{
"title": "B",
"data": [
{
"id": "320",
"name": "Bourjois"
},
{
"id": "321",
"name": "Bioderma"
}
]
}
]
kindly help.
Thanks
i got this now:
i made this update.. but still not the needed result.
this is my php code...
$result = [];
foreach ($data as $item) {
$firstLetter = substr($item['name'], 0, 1);
$result[] = [
'title' => $firstLetter = ctype_alnum($firstLetter) ? $firstLetter : '#',
'data' => $item
];
}
foreach ($result as $key => $item) {
$arr[$item['title']][$key] = $item;
}
and this is the result.
{
"A": [
{
"title": "A",
"data": {
"brand_id": "312",
"brand_name": "Adidsa"
}
},
{
"title": "A",
"data": {
"id": "314",
"name": "Adio"
}
},
still can't find make the needed response..
This is not perfomance optimized, but shows a simple solution.
Collect all data grouped by title, then reformat the array to your expected result.
$array = json_decode($json, true);
$collect = [];
foreach($array as $item) {
$collect[$item['title']][] = $item['data'];
}
ksort($collect);
$titles = [];
foreach($collect as $title => $data) {
$names = array_column($data, 'name');
array_multisort($names, SORT_ASC, SORT_STRING, $data);
$titles[] = ['title' => $title, 'data' => $data];
}
echo json_encode($titles, JSON_PRETTY_PRINT); results in
[
{
"title": "A",
"data": [
{
"id": "317",
"name": "Aesethetica"
},
{
"id": "318",
"name": "Astonos"
}
]
},
{
"title": "B",
"data": [
{
"id": "321",
"name": "Bioderma"
},
{
"id": "320",
"name": "Bourjois"
}
]
}
]

Insert value in array after every index using php

I have fetch value from database and returning its array in json format. This is my code to get values. First array is working fine. But i need to add static array after every index in array. This is my code
$value = $this->TestModel->get_user_details($userIds);
this function returns array in json format e.g.
[
{
"user_id": "1",
"name": "test 1",
},
{
"user_id": "2",
"name": "test 2",
},
{
"user_id": "3",
"name": "test 3",
},
]
now i need to add below static json array with every item of array. This is e.g
$test1= array("student_list"=> array(array("stu_id"=>1, "name"=> "abc") , array("stu_id"=>2, "name"=> "xyz")),
"class"=> "12th",
"average_score"=>"5",
"results"=>array(array("result_date"=>"2012-12-13","city"=>"city 1"),array("result_date"=>"2015-10-13","city"=>"city 2")));
I have tried it with array_push and array_merge but it add this at the end end of array.
I need this Response
[
{
"user_id": "1",
"name": "test 1",
"student_list": [
{
"stu_id": 1,
"name": "abc",
},
{
"stu_id": 2,
"name": "xyz",
}
],
"class": "12th",
"average_score": "5",
"results": [
{
"result_date": "2012-12-13",
"city": "City 1",
},
{
"result_date": "2012-10-13",
"city": "City 2",
}
]
},
{
"user_id": "2",
"name": "test 2",
"student_list": [
{
"stu_id": 3,
"name": "asd",
},
{
"stu_id": 4,
"name": "ghj",
}
],
"class": "10th",
"average_score": "5",
"results": [
{
"result_date": "2011-12-13",
"city": "City 3",
},
{
"result_date": "2011-10-13",
"city": "City 4",
}
]
},
]
If you want to add $test1 to to every element you your array you should merge each element, like so:
$value = $this->TestModel->get_user_details($userIds);
$test1 = array(
"student_list" => array(array("stu_id" => 1, "name" => "abc"), array("stu_id" => 2, "name" => "xyz")),
"class" => "12th",
"average_score" => "5",
"results" => array(array("result_date" => "2012-12-13", "city" => "city 1"), array("result_date" => "2015-10-13", "city" => "city 2"))
);
$decoded = json_decode($value, true);
for ($i = 0; $i < count($decoded); $i++) {
$decoded[$i] = array_merge($decoded[$i], $test1);
}
$value = json_encode($decoded);

filtering json data in php laravel

I've a sample json data
"regions": [
{
"id": 1,
"name": "Region 1",
"state_id": 1,
"areas" :[ {
"id": 1,
"name": "area 1",
"region_id": 1},
{
"id": 2,
"name": "area 2",
"region_id": 1}
]
},
{
"id": 2,
"name": "Region 2",
"state_id": 1,
"areas" :[ {
"id": 3,
"name": "area 3",
"region_id": 2},
{
"id": 4,
"name": "area 4",
"region_id": 2}
]
}
]
How can I filter out the data the based on id in the regions? For example, if id is 2, then the response should be like
"regions": [
{
"id": 2,
"name": "Region 2",
"state_id": 1,
"areas" :[ {
"id": 3,
"name": "area 3",
"region_id": 2},
{
"id": 4,
"name": "area 4",
"region_id": 2}
]
}
]
You can json_decode that json string and then use array_filter method to filter regions
$regions = json_decode('{"regions":
[
{
"id": 1,
"name": "Region 1",
"state_id": 1,
"areas" :[ {
"id": 1,
"name": "area 1",
"region_id": 1
},{
"id": 2,
"name": "area 2",
"region_id": 1
}]
},{
"id": 2,
"name": "Region 2",
"state_id": 1,
"areas" :[{
"id": 3,
"name": "area 3",
"region_id": 2
},{
"id": 4,
"name": "area 4",
"region_id": 2
}]
}
]
}', true);
// Filter Region
$region_id = 2;
$filtered_regions = array_filter($regions['regions'], function($r) use ($region_id) {
return $r['id'] == $region_id;
});
// Filter By Area Id
$area_id = 2;
$filtered_areas = array_filter($regions['regions'], function($r) use ($area_id) {
$areas = array_filter($r['areas'], function($area) use ($area_id) {
return $area['id'] == $area_id;
});
return count($areas) > 0;
});
return ['regions' => $filtered_regions];
First apply json_decode on your json data then apply filter . If you want to get an whole object from this response array , then write a function which will accept the id and return that object after filtering.

Loop through every occurrence of specific child key in a nested structure

I have this payload,
[
{
"id": 1,
"name": "T-Shirt",
"children_rec": [
{
"id": 2,
"name": "Classic",
"children_rec": [
{
"id": 3,
"name": "Lycra",
"children_rec": []
}
]
},
{
"id": 4,
"name": "Plain",
"children_rec": []
}
]
},
{
"id": 5,
"name": "Shirt",
"children_rec": [
{
"id": 6,
"name": "Plain",
"children_rec": []
}
]
}
]
I want to loop through every occurrence of children_rec.
What I have tried is,
foreach ($mainCategories as $category) {
if (!empty($category['children_rec'])) {
foreach ($category['children_rec'] as $child) {
if (!empty($category['children_rec'])) {
var_dump($child);
}
}
}
}
But this is not the dynamic way to achieve this. What if I have 5 or 6 level of childer_rec. How can I achieve this?
Edit
#ggorlen's way is cool, but What if I need this output?
[
{
"id": 1,
"name": "T-Shirt",
"children": [
"2",
"3",
"4"
]
},
{
"id": 5,
"name": "Shirt",
"children": [
"6"
]
}
]
Since you don't know the depth, you'll need a stack or recursion. Here's a solution with a stack:
<?php
$tree = json_decode('[ { "id": 1, "name": "T-Shirt", "children_rec": [ { "id": 2, "name": "Classic", "children_rec": [ { "id": 3, "name": "Lycra", "children_rec": [] } ] }, { "id": 4, "name": "Plain", "children_rec": [] } ] }, { "id": 5, "name": "Shirt", "children_rec": [ { "id": 6, "name": "Plain", "children_rec": [] } ] } ]', true);
for ($stack = $tree; !empty($stack);) {
$curr = array_pop($stack);
$flattened[] = $curr["name"]; // or just $curr if you only want the node
if (!empty($curr["children_rec"])) {
array_push($stack, ...$curr["children_rec"]);
}
}
print_r($flattened);
Array
(
[0] => Shirt
[1] => Plain
[2] => T-Shirt
[3] => Plain
[4] => Classic
[5] => Lycra
)
If order is important, you can array_reverse all arrays as you push them onto the stack without harming the linear time complexity.
For the updated specification, just plop the above code into a function and call it for each root node:
<?php
function flatten($tree) {
for ($stack = array_reverse($tree); !empty($stack);) {
$curr = array_pop($stack);
$flattened[] = $curr["id"];
if (!empty($curr["children_rec"])) {
array_push($stack, ...array_reverse($curr["children_rec"]));
}
}
return $flattened;
}
$tree = json_decode('[ { "id": 1, "name": "T-Shirt", "children_rec": [ { "id": 2, "name": "Classic", "children_rec": [ { "id": 3, "name": "Lycra", "children_rec": [] } ] }, { "id": 4, "name": "Plain", "children_rec": [] } ] }, { "id": 5, "name": "Shirt", "children_rec": [ { "id": 6, "name": "Plain", "children_rec": [] } ] } ]', true);
foreach ($tree as &$root) {
$root["children"] = flatten($root["children_rec"]);
unset($root["children_rec"]);
}
echo json_encode($tree, JSON_PRETTY_PRINT)."\n";
Output:
[
{
"id": 1,
"name": "T-Shirt",
"children": [
2,
3,
4
]
},
{
"id": 5,
"name": "Shirt",
"children": [
6
]
}
]

Group and reformat an array of objects in PHP

I have the following performance problem in PHP code. An external API that I cannot edit, returns a JSON array like this one:
[{"name": "Name 1", "code": "Code 1", "attribute1": "Black", "attribute2": "32", "price": "10"},
{"name": "Name 2", "code": "Code 2", "attribute1": "Yellow", "attribute2": "", "price": "15"},
{"name": "Name 1", "code": "Code 3", "attribute1": "Yellow", "attribute2": "32", "price": "20"},....
]
I want to group this by name and reformat it to a JSON array like this:
[{
"name": "Name 1",
"available_attributes": [ "size", "color" ],
"variations": [
{ "attributes": { "size": "32", "color": "Black" }, "price": "10", "code": "Code 1"},
{ "attributes": { "size": "32", "color": "Yellow" }, "price": "20", "code": "Code 3"}
]
}, {
"name": "Name 2",
"available_attributes": [ "color" ],
"variations": [ { "attributes": { "color": "Yellow" }, "price": "15", "code": "Code 2"}]
}]
My solution is ugly and time-consuming since I used a simple brute force to iterate on the response and then again every time on the array to update the one I have already there.
So, I am looking for a solution focused on performance and speed.
Edit. This is my code. The only difference is that in case of both attributes being empty, instead of the variations and available_attributes arrays, it has the price and the sku only.
function cmp( $a, $b ) {
if ( $a['name'] == $b['name'] ) {
return 0;
}
return ( $a['name'] < $b['name'] ) ? - 1 : 1;
}
function format_products_array($products) {
usort( $products, "cmp" );
$formatted_products = array();
$new = true;
$obj = array();
for ( $i = 0; $i < count( $products ); $i++ ) {
if ( $new ) {
$obj = array();
$attr = array();
$obj['available_attributes'] = array();
$obj['variations'] = array();
$obj['name'] = $products[$i]['name'];
if ( $products[$i]['attribute1'] != '' ) {
array_push( $obj['available_attributes'], 'color' );
$attr['color'] = $products[$i]['attribute1'];
}
if ( $products[$i]['attribute2'] != '' ) {
array_push( $obj['available_attributes'], 'size' );
$attr['size'] = $products[$i]['attribute2'];
}
}
if ( $products[ $i ]['name'] == $products[ $i + 1 ]['name']) {
$new = false;
$attr['size'] = $products[$i]['attribute2'];
$attr['color'] = $products[$i]['attribute1'];
if ( empty($obj['available_attributes']) ) {
$obj['price'] = $products[$i]['price'];
} else {
$var = array();
$var['price'] = $products[$i]['price'];
$var['code'] = $products[$i]['code'];
$var['attributes'] = $attr;
array_push($obj['variations'], $var);
}
} else {
$new = true;
if ( empty($obj['available_attributes']) ) {
$obj['price'] = $products[$i]['price'];
}
$attr['size'] = $products[$i]['attribute2'];
$attr['color'] = $products[$i]['attribute1'];
$var['attributes'] = $attr;
array_push($obj['variations'], $var);
array_push($formatted_products, $obj);
}
}
return $formatted_products;
}
A faster solution is when generating the array to store the unique identifies or each object eg to generate:
[
"Name1":{
"name": "Name 1",
"code": "Code 1",
"available_attributes": [ "size", "color" ],
"variations": [
{ "attributes": { "size": "32", "color": "Black" }, "price": "10"},
{ "attributes": { "size": "32", "color": "Yellow" }, "price": "20"}
]
},
"Name2": {
"name": "Name 2",
"code": "Code 2",
"available_attributes": [ "color" ],
"variations": [ { "attributes": { "color": "Yellow" }, "price": "15"}]
}]
OR
[
"Code 1":{
"name": "Name 1",
"code": "Code 1",
"available_attributes": [ "size", "color" ],
"variations": [
{ "attributes": { "size": "32", "color": "Black" }, "price": "10"},
{ "attributes": { "size": "32", "color": "Yellow" }, "price": "20"}
]
},
"Code 2": {
"name": "Name 2",
"code": "Code 2",
"available_attributes": [ "color" ],
"variations": [ { "attributes": { "color": "Yellow" }, "price": "15"}]
}]
Afterwards (optionally)remove any association.
Afterwards you may store them in a memcached/redis then when you need to re-retrieve the same data then just look in redis/memcached first.
So it may be time consuming at first but afterwards it will be ready to do that so they will be only on "unlucky" guy/girl who will do the very same thing.
In case it is extreemely time consuming loops then use a worker to generate theese data ans store them in an document-based storage such as mongodb/couchdb afterwards the site will look on the ready made document.

Categories