Json Nested arrays to single array using php - php

I have a nested JSON. I wanted to convert it to simple json in php
var movies = [{
"name": "Ice Age 3",
"place" : "USA",
"actors" : "cartoon",
"details": [
{"language": "English", "year": "2012"},
{"language": "French", "year": "2011"},
{"language": "German", "year": "2013"}
],
"details2": [
{"language2": "Spanish", "year2": "2015"},
{"language2": "Arabic", "year2": "2016"},
{"language2": "Hindi", "year2": "2017"}
]
}];
like this...
var movies = [
{"name":"Ice Age 3","place" : "USA", "actors" : "cartoon", "details.language":"English", "details.year":"2012", "details2.language2":"English", "details2.year2":"2015"},
{"name":"Ice Age 3","place" : "USA", "actors" : "cartoon", "details.language":"French", "details.year":"2011", "details2.language2":"French", "details2.year2":"2016"},
{"name":"Ice Age 3","place" : "USA", "actors" : "cartoon", "details.language":"German", "details.year":"2013", "details2.language2":"German", "details2.year2":"2017"}
];
When i tried this way, i am getting a flat json .
function convert_flatten($array) {
if (!is_array($array)) {
return FALSE;
}
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$arrayList=convert_flatten($value);
foreach ($arrayList as $listItem) {
$result[] = $listItem;
}
}
else {
$result[$key] = $value;
}
}
return $result;
}
This actually is a representation json. Iam looking for a generic answer.
Any help will be appreciated
Thanks

Similar to Prashant's answer...
$movies = '[{
"name": "Ice Age 3",
"details": [
{"language": "English", "year": "2012"},
{"language": "French", "year": "2011"},
{"language": "German", "year": "2013"}
]
}]';
$movies = json_decode($movies, true);
$out = array();
foreach ( $movies as $movie ) {
foreach ( $movie['details'] as $movieDetails ){
$movieDetails['name'] = $movie['name'];
$out[] = $movieDetails;
}
}
echo json_encode($out);
Outputs...
[{"language":"English","year":"2012","name":"Ice Age 3"},
{"language":"French","year":"2011","name":"Ice Age 3"},
{"language":"German","year":"2013","name":"Ice Age 3"}]
Rather than trying to manipulate the content as some sort of anonymous JSON, this code just works with the data presented. Each element within the original JSON is processed one at a time (potentially allowing multiple movies with the same structure to be present) and just promotes each of the details array elements to the top level in $out (adding the name of the film into this each time).

try this
$(function () {
var movies = [{
"name": "Ice Age 3",
"details": [
{"language": "English", "year": "2012"},
{"language": "French", "year": "2011"},
{"language": "German", "year": "2013"}
]
}];
var obj = JSON.parse(JSON.stringify(movies));
var obj2;
jsonObj = [];
for (var i = 0; i < obj.length; i++) {
item = {};
obj2 = JSON.parse(JSON.stringify(obj[i].details));
for (var j = 0; j < obj2.length; j++) {
item ["name"] = obj[i].name;
item ["language"] = obj2[j].language;
item ["year"] = obj2[j].year;
jsonObj.push(item);
}
}
var data = JSON.stringify(jsonObj);
alert(data);
});

You don't need to recurse to do this, this is untested but will give a grounding for what you need;
function flattenMovies($data)
{
// Get the name of the movie
$name = $data['name'];
$return_val = array();
// For each part of this...
foreach ($data as $part)
{
// If it is an array...
if (is_array($part))
{
// Create a new array for this row and add the movie name
$add_parts = array("name" => $name);
// For each of the parts parts...
foreach ($part as $key => $value)
{
// Add this to the row array assoc by key = value
$add_parts[$key] = $value;
}
// Add the row to the return array
$return_val[] = $add_parts;
// Blank this row so we know this does not have any "old" info in
$add_parts = null;
}
}
// Return the flattened array
return $return_val;
}
All you need to do is traverse the array and add the parts to a single array of values
You may need to add another nesting into the foreach, as I say, untested

Related

remapping and grouping repeated values from an array in php

I am trying to remap an response from a query to the database and group like items in one array. for example, from this example below.
Response:
[
"Location"=> "City 1",
"AptDate"=> "2020-09-16",
"AptTime"=> "11:00",
"AptLength"=> "45",
"AptStatus"=> "1",
"Operatory"=> "1 RECALL",
"OperatoryNum"=> "2"
],
[
"Location"=> "City 2",
"AptDate"=> "2020-09-16",
"AptTime"=> "09:00",
"AptLength"=> "45",
"AptStatus"=> "1",
"Operatory"=> "1 RECALL",
"OperatoryNum"=> "2"
],
[
"Location"=> "City 1",
"AptDate"=> "2020-09-16",
"AptTime"=> "12:00",
"AptLength"-> "45",
"AptStatus"=>"1",
"Operatory"=> "1 RECALL",
"OperatoryNum"=> "2"
[,
looping through results:
$remappedData=[];
foreach ($result as $value)
{
$remappedData[] = [
'location' => $value['Location'],
// And so on
];
}
}
This doesnt really give me what i need as I am trying to group the array based on Location and add the AppDate base on that location. Something like this.
{
"Location": "City 1",
"AptDate": ["2020-09-16","2020-09-16"],
"AptTime": ["11:00","12:00"],
"AptLength": ["45","45"],
"AptStatus": ["1","1"],
"Operatory": ["1 RECALL","1 RECALL"],
"OperatoryNum": ["2","2"]
},
{
"Location": "City 2",
"AptDate": ["2020-09-16"],
"AptTime": ["09:00"],
"AptLength":[ "45"],
"AptStatus": ["1"],
"Operatory": ["1 RECALL"],
"OperatoryNum": "2"
},
So based on your scenario, you want grouping on Location and group all other attributes by keeping them in array.
foreach ($result as $value)
{
$remappedData[$value['Location']]['location'] = $value['Location'];
$remappedData[$value['Location']]['AptDate'][] = $value['AptDate']; // Notice we're creating an array here.
$remappedData[$value['Location']]['AptTime'][] = $value['AptTime'];
// so on all other attributes which needs to be grouped.
}
Note: Here we've created index as Location. If we don't want Location as key, we want as array(may be for frontend) use below code.
$temp = [];
$remappedData=[];
$intCurrentIndex = -1;
foreach ($result as $value)
{
if(isset($temp[$value['Location']])){
$oldIndex = $temp[$value['Location']];
$remappedData[$oldIndex]['AptDate'][] = $value['AptDate'];
$remappedData[$oldIndex]['AptTime'][] = $value['AptTime'];
}
else{
$temp[$value['Location']] = ++$intCurrentIndex;
$remappedData[$intCurrentIndex]['location'] = $value['Location'];
$remappedData[$intCurrentIndex]['AptDate'][] = $value['AptDate'];
$remappedData[$intCurrentIndex]['AptTime'][] = $value['AptTime'];
}
}

Group PHP array values based on 2 sub-values

I have called a JSON array from an API and used json_decode to assign them to a PHP variable.
The array looks like this:
[
{
"id": "1",
"abbr": "XXX",
"title": "YYY",
"visible_from_lat": "85",
"visible_to_lat": "-75",
},
{
"id": "2",
"abbr": "AAA",
"title": "BBB",
"visible_from_lat": "85",
"visible_to_lat": "-75",
}
]
The array has approx 50 items in total, all of which have a visible_from_lat and a visible_to_lat. What I need to do is group each items like so:
visible_from_lat > 0 then assign to variable1
visible_from_lat < 0 then assign to variable2
Any idea's how I do this?
Here there is a basic solution, assuming that in data.json file there are your json data:
<?php
$array = json_decode(file_get_contents("data.json"));
$resulSetPositive = [];
$resulSetNegative = [];
foreach ($array as $obj) {
if(isset($obj->visible_from_lat)) {
if($obj->visible_from_lat > 0) {
$resulSetPositive[] = $obj; // add obj to positive result set
}
else if($obj->visible_from_lat < 0) {
$resulSetNegative[] = $obj; // add obj to negative result set
}
}
}
file_put_contents("negative.json", json_encode($resulSetNegative, JSON_PRETTY_PRINT));
file_put_contents("positive.json", json_encode($resulSetPositive, JSON_PRETTY_PRINT));

create tree view like json from existing combined array

I have one combined array of order and its items combined into one array but i am trying to create json structure like order then its items list like wise.
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'abc',"price"=>250);
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'xyz',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'pqr',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'lmn',"price"=>250);
Output should be like
[
"0":[
{
"OrderNo": "1",
"partycode": "10",
"OrderDetails": [
{
"Item": "abc",
"price": 250
},
{
"Item": "xyz",
"price": 250
}
]
}
],
"1":[
{
"OrderNo": "2",
"partycode": "20",
"OrderDetails": [
{
"Item": "pqr",
"price": 250
},
{
"Item": "lmn",
"price": 250
}
]
}
]
]
This is What i Tried
$mainarray = array();
$orderarray = array();
$orderitemarray = array();
if (count(combinedarray) > 0) {
foreach (combinedarray as $obj) {
$orderarray[] = array("orderid" => $obj->orderid);
$orderitemarray[] = array("Item" => $obj->Item, "price" => $obj->price);
}
}
$mainarray[] = array_unique($orderarray);
$mainarray['OrderDetails'] = $orderitemarray;
echo json_encode($mainarray);
$mainarray = array();
foreach ($combinedarray as $x) {
$id = $x['orderid'];
unset($x['orderid']);
if (! isset($mainarray[$id])) {
$mainarray[$id]['OrderNo'] = $id;
}
$mainarray[$id]["OrderDetails"][] = $x;
}
// Now $mainarray has indexes equal to OrderNo. To count it from zero, use array_values
echo json_encode(array_values($mainarray), JSON_PRETTY_PRINT);
demo
By your given array
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'abc',"price"=>250);
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'xyz',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'pqr',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'lmn',"price"=>250);
Here is my solution for this
$new = array();
foreach($combinedarray as $r){
$new[$r['orderid']]['orderid'] = $r['orderid'];
$new[$r['orderid']]['partycode'] = $r['partycode'];
$new[$r['orderid']][] = array("item"=>$r['item'],"price"=>$r['price']);
}
$json = json_encode($new);
echo '<pre>';print_r($new);
echo $json;

PHP - object array into json

array of $setting['accountType'] :
$setting['accountType']['all'] = 'ALL';
$setting['accountType']['A1'] = 'VIP1';
$setting['accountType']['A2'] = 'VIP2';
PHP code to generate the object:
$object = new stdClass();
$myArray = array();
foreach ($setting['accountType'] as $key => $val)
{
$object->id = $key;
$object->desc = $val;
$myArray[] = $object;
}
$accountType = $myArray;
PHP code to format object into json:
json_encode(['accountType'=> [(object)$accountType]));
However, i get the output as below :
"accountType": [{
"0": {
"id": "A2",
"desc": "VIP"
},
"1": {
"id": "A2",
"desc": "VIP"
},
"2": {
"id": "A2",
"desc": "VIP"
}
}]
Problem 1: why $accountType only keep the last object when I loop through?
Problem 2: without the array key of $accountType [solved by using array_values($accountType)]
This is something that I am trying to achieve:
"accountType": [{
"id": "all",
"desc": "All "
}, {
"id": "A1",
"desc": "Normal"
}, {
"id": "A2",
"desc": "VIP"
}]
How to get the output as above?
You should use
json_encode(['accountType'=> $accountType]);
instead of
json_encode(['accountType'=> [(object)$accountType]]);
In your code you are putting $accountType inside another array that is why you are getting that result
Here is a Demo and Explanation
Edit: The entire code
$setting['accountType']['all'] = 'ALL';
$setting['accountType']['A1'] = 'VIP1';
$setting['accountType']['A2'] = 'VIP2';
$myArray = array();
foreach ($setting['accountType'] as $key => $val)
{
$object = new stdClass(); // Note: $object should be created inside the loop
$object->id = $key;
$object->desc = $val;
$myArray[] = $object;
}
$accountType = $myArray;
echo json_encode(['accountType'=> $accountType]);
And Here is the Revised Demo
Try this,
echo json_encode(array_values($your_array));
Let me know if its working
This is exactly the same thing, no?
The numerotation is displayed because you need it to access to the specific json object.
You have an array and you can access to each element by its key.

PHP get array items based on string mask

i have an array with a bunch of records like in:
{
"ID": "38424",
"heading": "Nylies soek nuwe hoof",
"typeID": "1",
"datein": "2016-09-26 12:14:16",
"edited_datein": null,
"publishDate": "2016-09-23 00:00:00",
"category": {
"ID": "1",
"heading": "News",
"typeID": "3",
"datein": "2016-09-26 11:50:06",
"edited_datein": null,
"url": "news"
},
"authorID": "592",
"tags": "skool,school,hoof,headmaster,etienne burger"
}
i have another array with "columns" i want the records to be "filtered" by
{
"ID",
"heading",
"datein",
"category|heading",
"category|url"
}
i would like the result to create a multidimensional array based on the column items:
{
"ID": "38424",
"heading": "Nylies soek nuwe hoof",
"datein": "2016-09-26 12:14:16",
"category": {
"heading": "News",
"url": "news"
}
}
how do i achieve this? i'm totally stuck on this now :( busy trying a hack of array_combine now but i dont hold much hope it would work out
so after being stuck on this for many hours.. and posting it here. i found a solution
$new_list = array();
foreach ($n as $record) {
$new_list[] = filter_columns($columns, $record);
}
and the function:
function filter_columns($columns, $record, $pre="") {
$return = array();
foreach ($record as $key => $value) { // loop through the fields in the record
$str = $pre.$key; // create a string of the current key
if (in_array($str,$columns)){
$return[$key] = $value;
}
if (is_array($value)){
$return[$key] = filter_columns($columns, $value,$key."|"); // if the value is an array recall the function but prepend the current key| to the key mask
}
}
return $return;
}

Categories