Below is my JSON and i wan to get all key as "node"and "id" of that node.
[
{
"id": 15,
"title": " Introduction",
"node": {
"id": 15,
"title": " Introduction",
"description": " Introduction on travelling abroad",
"media_info": " Introduction on travelling abroad",
"thumb_url": "test",
"media_url": "test"
},
"children": [
{
"id": 16,
"title": "Travel Preparation",
"node": {
"id": 16,
"title": "Travel Preparation",
"description": " Travel Preparation",
"media_info": "Travel Preparation",
"thumb_url": "test",
"media_url": "test"
},
"children": [
{
"id": 17,
"title": "The Act of Traveling",
"node": {
"id": 17,
"title": "The Act of Traveling",
"description": " The Act of Traveling",
"media_info": "The Act of Traveling",
"thumb_url": "/test",
"media_url": "test"
}
}
]
},
{
"id": 18,
"title": "Arrival at Your Destination Abroad",
"node": {
"id": 18,
"title": "Arrival at Your Destination Abroad",
"description": " Arrival at Your Destination Abroad",
"media_info": "Arrival at Your Destination Abroad",
"thumb_url": "test",
"media_url": "test"
},
"children": [
{
"id": 19,
"title": "In Your Destination Country",
"node": {
"id": 19,
"title": "In Your Destination Country",
"description": " In Your Destination Country",
"media_info": "In Your Destination Country",
"thumb_url": "http:test",
"media_url": "test"
}
}
]
}
]
}
]
========================================================================
I am using below code but it is not giving the correct output.
I want out put should be 15,16,17,18.
$obj = json_decode($config_info, true);
foreach ($obj as $key => $value) {
print_r($value['node']['id']);
}
You could try with array_walk_recursive function :
$ids = array();
$data = json_decode($json, true);
array_walk_recursive($data, function($v, $k) use (&$ids) {
if ($k === 'id') {
$ids[] = $v;
}
});
$ids = array_unique($ids);
var_dump($ids);
In your code, $value['node']['id'] refer to the ['node']['id'] key, so it will give you only one output.
In you want others, you have to fetch "children" key as well. Like this for instance :
$obj = json_decode($json, true);
foreach ($obj as $key => $value) {
echo $value['node']['id']; // return 15
$children = $value['children'];
if(is_array($children)){
foreach ($children as $child){
if(is_array($child['children'])){
foreach($child['children'] as $secondLevelChild){
echo $secondLevelChild['id'];// return 17 and 19;
}
}
echo $child['id']; // return 16 and 18
}
}
}
And you can use the same method to retrieve the 17 result as well in the second level of children key, see the code above.
Check it out:
$arr = json_decode($json, true);
$ids = array();
function get_ids($arr){
global $ids;
foreach($arr as $key => $value){
if($key == 'node')
$ids[] = $value['id'];
if(is_array($value))
get_ids($value);
}
}
get_ids($arr);
echo '<pre>';
print_r(array_unique($ids));
Result:
Array
(
[0] => 15
[2] => 16
[4] => 17
[6] => 18
[7] => 19
)
Related
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);
}
}
I have 2 JSON files that I would like to parse, and merge into one object and output as a single JSON.
but I can't figure out how to do and get the correct result, every time i try always get a single result like this :
[
{
"Title": "Some title for your blog",
"url": "\/post.php?id=1",
"image": "https:\/\/example.com\/images\/small\/1.jpg"
}
]
what i need is to call all the 2 json data to 1 json like this one :
[
{
"Title": "second title for your blog",
"url": "\/post.php?id=2",
"image": "https:\/\/example.com\/images\/small\/2.jpg"
}
{
"Title": "second title for your blog",
"url": "\/post.php?id=2",
"image": "https:\/\/example.com\/images\/small\/2.jpg"
}
{
"Title": "third title for your blog",
"url": "\/post.php?id=3",
"image": "https:\/\/example.com\/images\/small\/3.jpg"
}
and so on... till the end of loop
]
Here is my code :
$requestUrl="http://example.com/json1.php";
$requestUrl1="http://example.com/json2.php";
$data=file_get_contents($requestUrl);
$data1=file_get_contents($requestUrl1);
$array1 = json_decode($data);
$array2 = json_decode($data1);
$wholedata= [];
$i=0;
foreach ($array1 as $array1) {
$item['Title'] = $array1->title;
$item['url'] = $array1->url;
}
foreach ($array2 as $array2) {
$item['image'] = $array2->image;
}
$wholedata[] = $item;
$i++;
$json = json_encode($wholedata, JSON_PRETTY_PRINT);
header('Access-Control-Allow-Origin: *');
header('Content-type: Application/JSON');
echo $json;
Here's the json data :
Json 1
[
{
"title": "first title for your blog",
"url": "/post.php?id=1"
},
{
"title": "Second title for your blog",
"url": "/post.php?id=2"
},
{
"title": "Third title for your blog",
"url": "/post.php?id=3"
},
{
"title": "Fourth title for your blog",
"url": "/post.php?id=4"
},
{
"title": "Fifth title for your blog",
"url": "/post.php?id=5"
}
]
Json 2 :
[
{
"image": "https://example.com/images/small/1.jpg"
},
{
"image": "https://example.com/images/small/2.jpg"
},
{
"image": "https://example.com/images/small/3.jpg"
},
{
"image": "https://example.com/images/small/4.jpg"
},
{
"image": "https://example.com/images/small/5.jpg"
}
]
To do this with objects (as you are currently using), you can use the index of the first array to get the data from the second array. Then build the output in one go with the components from both objects and add them to your output...
$array1 = json_decode($data);
$array2 = json_decode($data1);
$wholedata= [];
foreach ($array1 as $key => $itemData) {
$wholedata[] = ['Title' => $itemData->title,
'url' => $itemData->url,
'image' => $array2[$key]->image];
}
$json = json_encode($wholedata, JSON_PRETTY_PRINT);
Try deocoding the json in an array and then merge them. Check out the official PHP documentation
array-merge - Merges two array
json_decode - Converts json into an array
I am only interested in keys class and score and their values in my nested array. How can I only get these keys values to be printed out?
This is my $result array.
{ "images": [ { "classifiers": [ { "classifier_id": "default", "name": "default", "classes": [ { "class": "banana", "score": 0.562, "type_hierarchy": "/fruit/banana" }, { "class": "fruit", "score": 0.788 }, { "class": "diet (food)", "score": 0.528, "type_hierarchy": "/food/diet (food)" }, { "class": "food", "score": 0.528 }, { "class": "honeydew", "score": 0.5, "type_hierarchy": "/fruit/melon/honeydew" }, { "class": "melon", "score": 0.501 }, { "class": "olive color", "score": 0.973 }, { "class": "lemon yellow color", "score": 0.789 } ] } ], "image": "fruitbowl.jpg" } ], "images_processed": 1, "custom_classes": 0}
And this is my code logic.
foreach($result as $imgage => $classifier)
{
foreach($classifier["classes"] as $clas)
{
foreach($clas as $key => $value)
{
echo $key . ": " . $value;
}
}
}
This should work for you,
<?php
$string = '{"images":[{"classifiers":[{"classifier_id":"default","name":"default","classes":[{"class":"banana","score":0.562,"type_hierarchy":"/fruit/banana"},{"class":"fruit","score":0.788},{"class":"diet (food)","score":0.528,"type_hierarchy":"/food/diet (food)"},{"class":"food","score":0.528},{"class":"honeydew","score":0.5,"type_hierarchy":"/fruit/melon/honeydew"},{"class":"melon","score":0.501},{"class":"olive color","score":0.973},{"class":"lemon yellow color","score":0.789}]}],"image":"fruitbowl.jpg"}],"images_processed":1,"custom_classes":0}';
$array = json_decode($string,1);
foreach($array['images'] as $key => $images)
{
foreach($images['classifiers'] as $key => $classes)
{
foreach($classes['classes'] as $cls_score){
echo "class = ". $cls_score['class']. " & score = ". $cls_score['score'].PHP_EOL;
}
}
}
WORKING DEMO: https://3v4l.org/vF2RL
Can you try ?
$str = '{ "images": .... }';
// get associative array from json
$result = json_decode($str, true)['images'];
foreach ($result as $imgage => $classifiers) {
foreach ($classifiers["classifiers"] as $classifier) {
foreach ($classifier["classes"] as $clas) {
foreach ($clas as $key => $value) {
// you can add condition here to target only desired keys
echo $key . ": " . $value;
}
}
}
}
I have this array of object:
[
{
"id": 1,
"name": "Carbo",
"menus": [
{
"id": 33,
"name": "FloralWhite",
"image": {
"web": "https://lorempixel.com/640/360/food/?89722",
"mobile": "https://lorempixel.com/640/360/food/?89722",
"square": "https://lorempixel.com/640/360/food/?89722"
},
"logs": {
"price": 2
}
},
{
"id": 40,
"name": "LightGray",
"image": {
"web": "https://lorempixel.com/640/360/food/?63930",
"mobile": "https://lorempixel.com/640/360/food/?63930",
"square": "https://lorempixel.com/640/360/food/?63930"
},
"logs": {
"price": 2
}
},
]
}
]
What I want to achieve:
[
{
"id": 1,
"name": "Carbo",
"menus": [
{
"id": 33,
"name": "FloralWhite",
"image": {
"web": "https://lorempixel.com/640/360/food/?89722",
"mobile": "https://lorempixel.com/640/360/food/?89722",
"square": "https://lorempixel.com/640/360/food/?89722"
},
"price": 2
},
{
"id": 40,
"name": "LightGray",
"image": {
"web": "https://lorempixel.com/640/360/food/?63930",
"mobile": "https://lorempixel.com/640/360/food/?63930",
"square": "https://lorempixel.com/640/360/food/?63930"
},
"price": 2
},
]
}
]
I've tried using laravel collection flatten with depth but it fail
$data = collect($data->menus);
$data = $data->flatten(1);
$data->values()->all();
How can I flatten the menus['logs'] object so it can one level with menu?
Something like this should do the trick. Simply iterate over your array, set the new property and remove the one you don't want.
$data = json_decode("[{
\"id\": 1,
\"name\": \"Carbo\",
\"menus\": [
{
\"id\": 33,
\"name\": \"FloralWhite\",
\"image\": {
\"web\": \"https://lorempixel.com/640/360/food/?89722\",
\"mobile\": \"https://lorempixel.com/640/360/food/?89722\",
\"square\": \"https://lorempixel.com/640/360/food/?89722\"
},
\"logs\": {
\"price\": 2
}
},
{
\"id\": 40,
\"name\": \"LightGray\",
\"image\": {
\"web\": \"https://lorempixel.com/640/360/food/?63930\",
\"mobile\": \"https://lorempixel.com/640/360/food/?63930\",
\"square\": \"https://lorempixel.com/640/360/food/?63930\"
},
\"logs\": {
\"price\": 2
}
}
]
}]");
foreach($data as $val){
foreach($val->menus as $menuVal){
$menuVal->price = $menuVal->logs->price;
unset($menuVal->logs);
}
}
#Stefen Suhat i really don't know what is the syntax for laravel but i did it with a simple php foreach() hope this will help you, as your array's depth is long so i had gone to all the levels of your array, check code and output snippet here https://eval.in/806879
try below one:
<?php
$array = array(
array(
"id"=> 1,
"name"=> "Carbo",
"menus"=> array(
array(
"id"=> 33,
"name"=> "FloralWhite",
"image"=> array(
"web"=> "https=>//lorempixel.com/640/360/food/?89722",
"mobile"=> "https=>//lorempixel.com/640/360/food/?89722",
"square"=> "https=>//lorempixel.com/640/360/food/?89722"
),
"logs"=> array(
"price"=> 2
)
),
array(
"id"=> 40,
"name"=> "LightGray",
"image"=> array(
"web"=> "https=>//lorempixel.com/640/360/food/?63930",
"mobile"=> "https=>//lorempixel.com/640/360/food/?63930",
"square"=> "https=>//lorempixel.com/640/360/food/?63930"
),
"logs"=> array(
"price"=> 2
)
),
)
)
);
foreach($array as $key => $value){
foreach ($value as $key1 => $value1) {
if(is_array($value1) && $key1 == "menus"){
foreach($value1 as $key2 => $value2) {
foreach ($value2 as $key3 => $value3) {
if(is_array($value3) && $key3 == "logs"){
unset($array[$key][$key1][$key2][$key3]);
$array[$key][$key1][$key2] = array_merge($array[$key][$key1][$key2], $value3);
}
}
}
}
}
}
echo "array after<br>";
echo "<pre>";
print_r($array); //your array after
?>
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.