How to add children where empty in nested object? - php

I have a multidimensional array with over 200 nested objects which some have children and some don't.
I'm trying to add empty children to where leaf: false and children don't exist.
[{
"id": "GRP-25",
"text": "Name 1",
"leaf": false,
"children": [{
"id": "APP-222",
"text": "Another name",
"leaf": true
}]
},
{
"id": "GRP-25",
"text": "Name 2",
"leaf": false,
"children": [] // <- missing, need to add empty children
}
]
function addEmptyChildren(array &$data)
{
foreach ($data as $k => $v)
{
// recursive call
if (is_array($v)) {
addEmptyChildren($data[$k]);
continue;
}
if ($data['leaf'] === false && !property_exists('children', $k)) {
$data['children'] = [];
}
}
}
addEmptyChildren($result);

I think I see the problem. Based on is_array(), $data['leaf'], etc., it looks like the function is meant to deal with an array of arrays, probably from json_decode($json, true), rather than an array of objects. If that's the case, then property_exists is not the right way to check for children.
Instead of this:
if ($data['leaf'] === false && !property_exists('children', $k)) {
use isset() or array_key_exists() instead.
if ($data['leaf'] === false && !isset($data['children'])) {

A lot more going on in your loop than appears to be necessary.
$str = '[{
"id": "GRP-25",
"text": "Name 1",
"leaf": false,
"children": [{
"id": "APP-222",
"text": "Another name",
"leaf": true
}]
},
{
"id": "GRP-25",
"text": "Name 2",
"leaf": false
}
]';
$result = json_decode($str);
if (json_last_error() !== 0){echo json_last_error_msg();}
#print_r($result);
function addEmptyChildren(array &$data)
{
foreach ($data as $k => $v) {
if ($v->leaf === false && !isset($v->children)) {
$v->children = [];
}
}
}
addEmptyChildren($result);
echo json_encode($result, JSON_PRETTY_PRINT);
RESULT
[
{
"id": "GRP-25",
"text": "Name 1",
"leaf": false,
"children": [
{
"id": "APP-222",
"text": "Another name",
"leaf": true
}
]
},
{
"id": "GRP-25",
"text": "Name 2",
"leaf": false,
"children": []
}
]

Related

select2 optgroup json format using php

i want that type of output
{
"results": [
{
"text": "Group 1",
"children" : [
{
"id": 1,
"text": "Option 1.1"
},
{
"id": 2,
"text": "Option 1.2"
}
]
},
{
"text": "Group 2",
"children" : [
{
"id": 3,
"text": "Option 2.1"
}
]
}
]
}
here is my controller code but i can't match this type of json so please help me out
$att = array();
foreach ($products as $v ) {
if ( !isset($att[$v->supplier->name]) ) {
$att[$v->supplier->name] = array();
}
$att[$v->supplier->name][$v->id] = $v->prd_our_item_no.'-'.$v->prd_description;
}
i can't make key and text for each supplier can you guys help me out

Find latest children in nested categories php

I tried to parse a JSON using PHP from url. I need a list of item that have no children - means children field should be empty array and parent_id shouldn't be 0 - means not be parents.
JSON:
{
"body": {
"data": [
{
"id": 1,
"name": "car",
"parent_id": "0",
"children": [
{
"id": 2,
"name": "bmw",
"parent_id": "1",
"children": [
{
"id": 4,
"name": "bmw i8",
"parent_id": "2",
"children": []
}
]
},
{
"id": 3,
"name": "mustang",
"parent_id": "1",
"children": []
}
]
},
{
"id": 5,
"name": "clothes",
"parent_id": "0",
"children": []
},
{
"id": 6,
"name": "mobile",
"parent_id": "0",
"children": [
{
"id": 7,
"name": "apple",
"parent_id": "6",
"children": [
{
"id": 9,
"name": "Iphone 12 pro",
"parent_id": "7",
"children": []
},
{
"id": 10,
"name": "Iphone 11",
"parent_id": "7",
"children": []
}
]
},
{
"id": 8,
"name": "Xiaomi",
"parent_id": "6",
"children": []
}
]
}
]
}
}
Output Expected:
[4,3,9,10,8]
This is my php code that i tried and doesn't work.
$CategoryUrl = file_get_contents(self::CATEGORY_URL,true);
$array = json_decode($CategoryUrl,true);
$list = array();
foreach( $array['body']['data'] as $value ){
if (($value['parent_id'] != 0) && empty($value['children'])) {
foreach( $value['children'] as $val ){
$list[] = $val;
}
}
}
print_r($list);
It is indeed a little tricky to keep track of parent ID values and children call using array_walk_recursive as it jumps directly to its children. However, this can be still accomplished with your own recursive version like below. Keep checking with parent_id and children count. If both constraints satisfy, add them to $result, else keep calling children recursively.
<?php
$str = '{"body":{"data":[{"id":1,"name":"car","parent_id":"0","children":[{"id":2,"name":"bmw","parent_id":"1","children":[{"id":4,"name":"bmw i8","parent_id":"2","children":[]}]},{"id":3,"name":"mustang","parent_id":"1","children":[]}]},{"id":5,"name":"clothes","parent_id":"0","children":[]},{"id":6,"name":"mobile","parent_id":"0","children":[{"id":7,"name":"apple","parent_id":"6","children":[{"id":9,"name":"Iphone 12 pro","parent_id":"7","children":[]},{"id":10,"name":"Iphone 11","parent_id":"7","children":[]}]},{"id":8,"name":"Xiaomi","parent_id":"6","children":[]}]}]}}';
$data = json_decode($str,true);
$result = [];
function walkRecursive($data,&$result){
foreach($data as $entry){
if($entry['parent_id'] != 0 && count($entry['children']) == 0){
$result[] = $entry['id'];
}else{
walkRecursive($entry['children'],$result);
}
}
}
walkRecursive($data['body']['data'],$result);
print_r($result);
We can solve this problem by function call recursive algorithm,
hope it clear for you
$CategoryUrl = file_get_contents(self::CATEGORY_URL,true);
$array = json_decode($CategoryUrl, true);
$items = $array['body']['data'];
$list = [];
findParentIds(items, $list);
// doSomething
print_r($list);
/**
* passe by ref (list)
* #param array $children
* #param $list
*/
function findParentIds(array $children, & $list)
{
foreach ($children as $child) {
// use case 1: has no children and parent_id is 0 , just continue
if (empty($child['children']) && $child['parent_id'] == "0") {
continue;
}
// use case 2: has no children and parent_id is 0 , it's parent item
if (empty($child['children']) && $child['parent_id'] != "0") {
array_push($list, $child['id']);
}
// has children and parent_id is not 0 , recall function to treat use case 1 and 2 ..
findParentIds($child['children'], $list);
}
}

improving loop throw a schema on php

This is working, but feels really "dirty"
I have a schema json like:
[
{
"url": "http://www.google.com/api/updateVariable",
"verb": "POST",
"bodySchema": {
"type": "object",
"properties": {
"StoreId": {
"sync": "True",
"type": "integer"
},
"SKU": {
"sync": "True",
"type": "string"
},
"WareHouseId": {
"sync": "False",
"type": "integer"
},
"Stock": {
"sync": "True",
"type": "integer"
}
},
"required": [
"StoreId",
"SKU",
"Stock"
]
}
},
{
"url": "http://www.google.com/api/insertVariable",
"verb": "POST",
"bodySchema": {
"type": "object",
"properties": {
"StoreId": {
"sync": "True",
"type": "integer"
},
"SKU": {
"sync": "True",
"type": "string"
},
"WareHouseId": {
"sync": "False",
"type": "integer"
},
"Description": {
"sync": "True",
"type": "integer"
}
},
"required": [
"StoreId",
"SKU",
"Description"
]
}
}
]
And I want to loop throw all the properties (once again, this is working)
$result=json_decode($result, true);
while($item = array_shift($result)){
foreach ($item as $key => $value){
if($key=="bodySchema"){
foreach ($value as $key2 => $value3){
if($key2==properties)
var_dump($value3);
}
}
}
}
What I would like to have is something like:
$result=json_decode($result, true);
foreach($result as $mydata){
foreach($mydata->bodySchema->properties as $values){
var_dump($values->value);
}
}
is this possible?, I want to keep this code as clean and neat as possible
Yes, you can do it the way you want. You just have some syntax to cleanup to do.
In this example, $result is an associative array, so you can index into it just like any array.
$result = json_decode($result, true);
foreach ($result as $mydata) {
foreach ($mydata["bodySchema"]["properties"] as $propertyName => $schema){
var_dump([$propertyName, $schema]);
}
}
If you prefer object syntax, drop the true from json_decode.
$result = json_decode($result);
foreach ($result as $mydata) {
foreach ($mydata->bodySchema->properties as $propertyName => $schema){
var_dump([$propertyName, $schema]);
}
}

Parsing an array with PHP in a foreach loop

I want to parse an array with PHP's foreach loop to get the object names and values inside the 'ques' array.
[
{
"ques": [
{
"name": "comment",
"value": "comment me for the reason",
"sur_id": "1",
"user_id": "admin#gmail.com",
"pagename": "question_response"
},
{
"name": "check-box[]",
"value": "1"
},
{
"name": "radio",
"value": "radio 2"
},
{
"name": "yes",
"value": "no"
}
]
"ques":[
{
"name": "date",
"value": "2015-10-23"
},
{
"name": "select-deopdown",
"value": ""
},
{
"name": "true",
"value": "false"
},
{
"name": "number",
"value": "55"
}
]
}
]
I want to separate the value from the 'ques' array:
while ($fetch = mysql_fetch_array($query1)) {
$content = $fetch['CONTENT_VALUES'];
// print_r($content);
$content_value= mb_convert_encoding($content ,"UTF-8");
$datas = json_decode($content, true);
foreach($datas->ques as $values)
{
echo $values->value . "\n";
print_r($values);
}
$test[] = array('ques' => $datas ,'answer'=>$values);
}

Flatten a Multidimensional Array with key, value and object from a JSON

For 2 days, I'm trying to extract informations from a multidimensional array and I think I'm stuck after trying a lot of things
Here is my json
{
"profile": [
{
"id": "123456",
"hostId": null,
"description": [
{
"id": "name",
"value": "foo"
},
{
"id": "name2",
"value": "foo2"
},
{
"id": "bio",
"value": "heyyyy"
},
{
"id": "location",
"value": "somewhere"
}
],
"ishere": true
}
]
}
I want to manipulate it to have this
{
"id": "123456",
"host": null,
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere",
"ishere": true
}
with this (after a json_decode)
foreach ($array->profileUsers[0]->settings as $item) {
$out2[$item->id] = $item->value;
}
I only have
{
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere"
}
Thank you
This should do the trick:
$obj = json_decode($your_json);
$obj = $obj->profile[0];
foreach($obj->description as $d)
$obj->{$d->id} = $d->value;
unset($obj->description);
$data = json_decode($your_json, true);
$new_array = [];
foreach($data['profile'] as $key=>$item) {
if(is_array($item)) {
$new_array[$item['id']] = $item['value'];
}
else {
$new_array[$key] = $item;
}
}
Hardcoded this, hope it will help.

Categories