How to get parent array element in PHP with recursive function - php

I have PHP code as shown below which will print:
id:3deep:2path:image31.jpg
id:4deep:2path:image32.jpg
when I input deep = 2. However I would like to get parent array of this deep which is id = 2. Is there any way that I can do this?
Note:
Please see the result when I input deep as below:
> Deep = 1
ID = 0
ID = 1
ID = 2
ID = 7
ID = 8
> Deep = 2
ID = 2
ID = 3
ID = 4
> Deep = 3
ID = 4
ID = 5
ID = 6
Please check my code online.
PHP:
$obj = '{
"images": {
"deep": "1",
"id": "0",
"path": "image1.jpg",
"image": [
{
"deep": "1",
"id": "1",
"coordinate": "(x,y),(x,y)",
"path": "image2.jpg"
},
{
"deep": "1",
"id": "2",
"coordinate": "(x,y),(x,y)",
"path": "image3.jpg",
"image": [
{
"deep": "2",
"id": "3",
"coordinate": "(x,y),(x,y)",
"path": "image31.jpg"
},
{
"deep": "2",
"id": "4",
"coordinate": "(x,y),(x,y)",
"path": "image32.jpg",
"image": [
{
"deep": "3",
"id": "5",
"coordinate": "(x,y),(x,y)",
"path": "image321.jpg"
},
{
"deep": "3",
"id": "6",
"coordinate": "(x,y),(x,y)",
"path": "image322.jpg"
}
]
}
]
},
{
"deep": "1",
"id": "7",
"coordinate": "(x,y),(x,y)",
"path": "image4.jpg"
},
{
"deep": "1",
"id": "8",
"coordinate": "(x,y),(x,y)",
"path": "image5.jpg"
}
]
}
}';
$objArray = json_decode($obj,true);
$deep = 2;
$arr = all($objArray['images'], $deep);
display($arr);
function all($a, $d){
$temp = array();
if(is_array($a)){
foreach($a as $v){
all($v, $d);
}
if(isset($a['deep']) && $d == $a['deep']){
$temp['id'] = $a['id'];
$temp['deep'] = $a['deep'];
$temp['path'] = $a['path'];
$s =
'id:'.$a['id'].
'deep:'.$a['deep'].
'path:'.$a['path'];
display($s);
}
}
return ;
}
function display($a){
echo "<pre>";
print_r($a);
echo "</pre>";
}

Idk exactly what you want, but I changed your code a bit to filter in a nicer way and it adds the parent key to each $image so you can reference that afterwards.
You can set the $deep = null paramater to just add the parent to the image instead of filtering.
I hope you don't mind I changed the code style a bit, easier to read ( I hope :D )
Here's the code within phpfiddle: http://phpfiddle.org/main/code/8q0-c43
<?php
$obj = '{
"images": {
"deep": "1",
"id": "0",
"path": "image1.jpg",
"image": [
{
"deep": "1",
"id": "1",
"coordinate": "(x,y),(x,y)",
"path": "image2.jpg"
},
{
"deep": "1",
"id": "2",
"coordinate": "(x,y),(x,y)",
"path": "image3.jpg",
"image": [
{
"deep": "2",
"id": "3",
"coordinate": "(x,y),(x,y)",
"path": "image31.jpg"
},
{
"deep": "2",
"id": "4",
"coordinate": "(x,y),(x,y)",
"path": "image32.jpg",
"image": [
{
"deep": "3",
"id": "5",
"coordinate": "(x,y),(x,y)",
"path": "image321.jpg"
},
{
"deep": "3",
"id": "6",
"coordinate": "(x,y),(x,y)",
"path": "image322.jpg"
}
]
}
]
},
{
"deep": "1",
"id": "7",
"coordinate": "(x,y),(x,y)",
"path": "image4.jpg"
},
{
"deep": "1",
"id": "8",
"coordinate": "(x,y),(x,y)",
"path": "image5.jpg"
}
]
}
}';
$objArray = json_decode($obj, true);
function filter_deep(array $input, $deep = null, $parent = null) {
// store $results so we can return it
$result = array();
// loop over the $input
foreach ($input as $image) {
// set the parent passed alogn
$image['parent'] = $parent;
// add $image to $result if 'deep' == $deep
if ($deep === null || $image['deep'] == $deep) {
$result[] = $image;
}
// if the $image contains more child images recursively run this function again
// and merge the result with what we already have
if (isset($image['image']) && is_array($image['image'])) {
$result = array_merge($result, filter_deep($image['image'], $deep, $image));
}
}
return $result;
}
function display_image($image) {
return "id:{$image['id']} deep:{$image['deep']} path:{$image['path']} parent_id:{$image['parent']['id']} <br />\n";
}
// loop over the images that have deep == 2 and display them
foreach (filter_deep(array($objArray['images']), 2) as $image) {
echo display_image($image);
}
?>

Related

Is it possible to edit the elements of a json array to accomodate additional data/elements?

I'm retrieving data from a database and pushing it to arrays then use json_encode() to output in json format. I have ended up having the data in this format.
[
{
"category_id": "1",
"category_name": "Construction Materials"
},
{
"items": [
{
"id": "1",
"item_name": "Wire Mesh",
"price": "459",
"image_url": null
},
{
"id": "2",
"item_name": "Cement",
"price": "700",
"image_url": null
},
{
"id": "3",
"item_name": "Barbed Wire",
"price": "3000",
"image_url": null
},
{
"id": "4",
"item_name": "Iron sheet",
"price": "200",
"image_url": null
}
]
},
{
"category_id": "2",
"category_name": "Plumbing"
},
Here is what I want to achieve:
[
{
"category_id": "1",
"category_name": "Construction Materials"
"items": [
{
"id": "1",
"item_name": "Wire Mesh",
"price": "459",
"image_url": null
},
{
"id": "2",
"item_name": "Cement",
"price": "40",
"image_url": null
},
{
"id": "3",
"item_name": "Barbed Wire",
"price": "3000",
"image_url": null
},
{
"id": "4",
"item_name": "Iron sheet",
"price": "200",
"image_url": null
}
]
},
{
"category_id": "2",
"category_name": "Plumbing"
},
How can I achive this in php. Is it possible to edit the contents of the main array? how can I add "items" after "category_name"
Regards..
$array = json_decode($yourJson);
$arrayLength = count($array);
$finalArray = [];
for ($i=0; $i < $arrayLength; $i+=2) {
$finalArray[] = $array[$i] + $array[$i + 1];
}
$backToJson = json_encode($finalArray);
Alternative to Mattijs's answer.
function get_first_property($object) {
$properties = array_keys(get_object_vars($object));
return reset($properties);
}
function object_merge($object1, $object2) {
return (object) array_merge((array) $object1, (array) $object2);
}
// loop through each of the array objects
$previous_first_property = null;
foreach ($array as $i => $object) {
$first_property = get_first_property($object);
// merge if the 1st property is "items", and the previous 1st was "category_id"
if ($first_property == "items" && $previous_first_property == "category_id") {
$array[$i - 1] = object_merge($array[$i - 1], $array[$i]);
unset($array[$i]);
}
$previous_first_property = $first_property;
}

How to merge two JSON under an Array in PHP

I get details from the user through HTML form, and onclick the form submission, I run the php file, save2json.php, which retrieves from HTML form, and posts it as JSON in the file appointments.json.
save2json.php
$formdata = array(
$_POST['doctor'] => array(
'name'=> $_POST['name'],
'phone'=> $_POST['phone'],
'bday'=> $_POST['bday'],
'datepicker'=> $_POST['datepicker'],
)
);
$filetxt = 'appointments.json';
$arr_data = array();
if(file_exists($filetxt))
{
$jsondata = file_get_contents($filetxt);
$arr_data = json_decode($jsondata, true);
}
$arr_data[] = $formdata;
$jsondata = json_encode($arr_data, JSON_PRETTY_PRINT);
if(file_put_contents('appointments.json', $jsondata))
What I get: [appointments.json]
[{
"Doctor #3": {
"name": "0",
"phone": "0",
"bday": "0",
"datepicker": "0"
}
}, {
"Doctor #3": {
"name": "1",
"phone": "1",
"bday": "1",
"datepicker": "1"
}
}, {
"Doctor #1": {
"name": "2",
"phone": "2",
"bday": "2",
"datepicker": "2"
}
}, {
"Doctor #2": {
"name": "3",
"phone": "3",
"bday": "3",
"datepicker": "3"
}
}]
What I want: [appointments.json]
[{
"Doctor #3": [{
"name": "0",
"phone": "0",
"bday": "0",
"datepicker": "0"
},
{
"name": "1",
"phone": "1",
"bday": "1",
"datepicker": "1"
}
],
"Doctor #1": {
"name": "2",
"phone": "2",
"bday": "2",
"datepicker": "2"
},
"Doctor #2": {
"name": "3",
"phone": "3",
"bday": "3",
"datepicker": "3"
}
}]
If it is under same doctor, I want to make both objects come under the same array. And if it isn't like Doctor 1 and Doctor 2, in this case, I want them as separate apart from Doctor 3 array.
Thanks in Advance :)
This is the first attempt to put it inside the doctor array key:
<?php
// build the array
$docDetails = array(
'name'=> $_POST['name'],
'phone'=> $_POST['phone'],
'bday'=> $_POST['bday'],
'datepicker'=> $_POST['datepicker'],
);
// get the file's content as an array.
$filetxt = 'appointments.json';
if(file_exists($filetxt))
$arr_data = json_decode(file_get_contents($filetxt), true);
else
$arr_data = array();
$arr_data[$_POST['doctor']][] = $docDetails;
?>

How to merge JSON two indexes and then Parse information

I am trying to iterate both index of JSON(Players and Buildings), so that i can a get new result in jQuery
I have two index of JSON one having information of Players and second index having information of Building related Player.
I want to Parse it so that i can get Player and its building name.
My Actual JSON result
{
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
}
Need this
"information": [
{
"player_id": "35",
"Buildings_name": "ABC"
},
{
"player_id": "36",
"Buildings_name": "DEF"
},
{
"player_id": "37",
"Buildings_name": "GHI"
},
{
"player_id": "38",
"Buildings_name": "JKL"
}
]
}
Here you go, this go for each player and check if there are buildings and will map them to new structure. This will not filter values for buildings that do not have mapping to players, and will not include the buildings with no players.
var x = {
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
};
var res = $.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
})
and if you want to filter values that do not have relationships e.g INNER join
var resInnerJoin = $.grep($.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
}), function(it) {
return it.building_name != undefined
})
If you need it in PHP :
$json = '{...}';
// create and PHP array with you json data.
$array = json_decode($json, true);
// make an array with buildings informations and with building id as key
$buildings = array();
foreach( $array['Buildings'] as $b ) $buildings[$b['id']] = $b;
$informations = array();
for ( $i = 0 ; $i < count($array['Players']) ; $i++ )
{
$informations[$i] = array(
'player_id' => $array['Players'][$i]['id'],
'Buildings_name' => $buildings[$array['Players'][$i]['building_id']]['name']
);
}
$informations = json_encode($informations);
var_dump($informations);

group elements inside a json

I'm trying to make a json that looks like this:
{
"data": {
"error_message": "",
"data": {
"person": [
[
{
"name": "teset1",
"image": "http://test.co.il/test/icons/billadress.png"
},
{
"name": "test2",
"image": "http://test.co.il/test/icons/email.png"
},
{
"name": "test3",
"image": "http://test.co.il/test/icons/homeicon.png"
}
],
[
{
"name": "a",
"image": "http://test.co.il/shay/keykit/icons/billadress.png"
},
{
"name": "b",
"image": "http://test.co.il/shay/keykit/icons/email.png"
},
{
"name": "c",
"image": "http://dvns.co.il/shay/keykit/icons/homeicon.png"
}
],
[
{
"name": "a",
"image": "http://test.co.il/test/icons/billadress.png"
},
{
"name": "b",
"image": "http://test.co.il/test/icons/email.png"
},
{
"name": "c",
"image": "http://dvns.co.il/test/icons/homeicon.png"
}
],
]
}
},
}
This is the code i'm using after i'm getting the name & image from the mysql query:
$response = $this->_db->query($query)->result_array();
$icons_results = array();
$obj = new stdclass();
foreach ($response as $key => $response) {
$icons_model = new icons_model();
$icons_model->init($response);
$obj->families[] = $icons_model;
}
return $obj;
SO .. this is what i'm getting:
{
"data": {
"families": [
{
"id": "1",
"name": "a",
"image_url": "http://test.co.il/shay/keykit/icons/billadress.png"
},
{
"id": "2",
"name": "b",
"image_url": "http://test.co.il/shay/keykit/icons/email.png"
},
{
"id": "3",
"name": "c",
"image_url": "http://test.co.il/test/icons/homeicon.png"
},
{
"id": "6",
"name": "f",
"image_url": "http://test.co.il/test/icons/homeicon.png"
},
{
"id": "4",
"name": "d",
"image_url": "http://test.co.il/test/icons/billadress.png"
},
{
"id": "5",
"name": "e",
"image_url": "http://test.co.il/test/icons/billadres2323s.png"
},
and do on.
How to i make that every three object will be in a group? (like the first example)
Try this:
foreach ($response as $key => $response) {
$icons_model = new icons_model();
$icons_model->init($response);
$obj->families[(int)($key / 3)][] = $icons_model;
}

php json_encode formatting results?

I have:
$all = array(
array('id'=>1, 'cat'=>'Main','type'=>'Name0'),
array('id'=>2, 'cat'=>'Main','type'=>'Name1'),
array('id'=>3, 'cat'=>'Main','type'=>'Name3'),
array('id'=>4, 'cat'=>'Main','type'=>'Name4'),
array('id'=>5, 'cat'=>'Secondary','type'=>'Name5'),
array('id'=>6, 'cat'=>'Secondary','type'=>'Name6'),
array('id'=>7, 'cat'=>'Secondary','type'=>'Name7'),
array('id'=>8, 'cat'=>'Other','type'=>'Name8'),
array('id'=>9, 'cat'=>'Other','type'=>'Name9'),
array('id'=>10, 'cat'=>'Other','type'=>'Name10'),
array('id'=>11, 'cat'=>'Other','type'=>'Name11'),
);
$result = array();
foreach($all as $array){
$result[$array['cat']][] = array('id'=>$array['id'],'type'=>$array['type']);
}
$json_type = json_encode($result);
Which returns:
{"Main":[{"id":"1","type":"name1"},{"id":"2","type":"name2"},{"id":"3","type":"name3"},{"id":"4","type":"name4"}],"Secondary":[{"id":"5","type":"name5"},{"id":"6","type":"name6"},{"id":"7","type":"name7"}],"Other":[{"id":"8","type":"name8"},{"id":"9","type":"name9"},{"id":"10","type":"name10"},{"id":"11","type":"name11"}]}
But I need it to return as:
[
{
"text": "Main",
"children": [
{
"id": "1",
"text": "name1"
},
{
"id": "2",
"text": "name2"
},
{
"id": "3",
"text": "name3"
},
{
"id": "4",
"text": "name4"
}
]
},
{
"text": "Secondary",
"children": [
{
"id": "5",
"text": "name5"
},
{
"id": "6",
"text": "name6"
},
{
"id": "7",
"text": "name7"
}
]
},
{
"text": "Other",
"children": [
{
"id": "8",
"text": "name8"
},
{
"id": "9",
"text": "name9"
},
{
"id": "10",
"text": "name10"
},
{
"id": "11",
"text": "name11"
}
]
}
]
To work with the select2 JQuery plugin, I'm working with.
the 'children' name doesn't matter, I think that's just a placeholder so it gets parsed correctly. I'm not sure how I would go about it, I've been trying str_replace() but even that hasn't been working out so great.
I would to it in 2 loops. The first one to group results by category, the 2nd one to format it to fit your needs:
$temp = array();
foreach($all as $array){
if (!isset($temp[$array['cat']])) {
$temp[$array['cat']] = array();
}
$temp[$array['cat']][] = array('id'=>$array['id'], 'type'=>$array['type']);
}
$result = array();
foreach ($temp as $key=>$value) {
$result[] = array('text'=>$key, 'children'=>$value);
}
echo json_encode($result);
This produces the following output:
[{"text":"Main","children":[{"id":1,"type":"Name0"},{"id":2,"type":"Name1"},{"id":3,"type":"Name3"},{"id":4,"type":"Name4"}]},{"text":"Secondary","children":[{"id":5,"type":"Name5"},{"id":6,"type":"Name6"},{"id":7,"type":"Name7"}]},{"text":"Other","children":[{"id":8,"type":"Name8"},{"id":9,"type":"Name9"},{"id":10,"type":"Name10"},{"id":11,"type":"Name11"}]}]

Categories