group elements inside a json - php

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;
}

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;
}

What is the most efficient way to change a list to a nested object in php

I have a list of (the result of a query in DB) like this:
[
{
"id": "1",
"parent_id": null,
"title": "مدادنوکی",
"url": "/medadnoki"
},
{
"id": "2",
"parent_id": null,
"title": "جامعه",
"url": "/commiunity"
},
{
"id": "5",
"parent_id": "1",
"title": "درباره ی مدادنوکی",
"url": "/about"
},
{
"id": "6",
"parent_id": "1",
"title": "درباره ی مدادنوکی",
"url": "/about"
},
{
"id": "7",
"parent_id": "2",
"title": "همکاران",
"url": "/co-worker"
},
{
"id": "8",
"parent_id": "2",
"title": "اساتید",
"url": "/masters"
}
]
But I want to create an object like this:
[
{
"title": "مدادنوکی",
"url": "/medadnoki",
"subs" : [
{
"title": "درباره مدادنوکی",
"url": "/about"
},
{
"title": "درباره مدادنوکی",
"url": "/about"
},
{
"title": "درباره مدادنوکی",
"url": "/about"
},
{
"title": "درباره مدادنوکی",
"url": "/about"
}
]
},
{
"title": "جامعه",
"url": "/soc",
"subs" : [
{
"title": "همکاران",
"url": "/co-work"
},
{
"title": "اساتید",
"url": "/masters"
}
]
}
]
I have handled this process with two foreach in php and it means I process data twice and it is not efficient and will be slow.
Is there any Idea to doing this with just one foreach?
using one foreach means faster than two foreach twice and It will show the result in big data
Assuming you have the results in an order where the parents appear in the results before any children they may have, this should work:
$nested = [];
foreach($results as $r) {
if($r['parent_id'] === null) {
$nested[$r['id']] = [
'title' => $r['title'],
'url' => $r['url'],
'subs' => []
];
continue;
}
$nested[$r['parent_id']]['subs'][] = [
'title' => $r['title'],
'url' => $r['url']
];
}
$nested = array_values($nested);

Sorting only a part of object/array in PHP

I've been struggling around this for a while now and can't seem to get the right algorithm.
What I want is to sort this:
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}],
"position": "0"
}
}';
And the output would be
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
},{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}, {
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}],
"position": "0"
}
}';
So basically it should be sorted using the label inside the "options" without affecting the other fields. I've been trying usort and tried different algorithms but to no avail.
Current code that sorts only the outside "label" and not the inner label:
function optionsSort($a, $b) {
return strcmp($a['options'][0]['label'], $b['options'][0]['options']['label']);
}
usort($variable, "optionsSort"));
Here's the code:
// your array
$variable = '{
"0": {
"id": "0",
"code": "main_colour",
"label": "Main Colour",
"options": [{
"id": "825",
"label": "White",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "Cream",
"products": ["3", "4", "5"]
}],
"position": "0"
},
"2": {
"id": "0",
"code": "size",
"label": "Size",
"options": [{
"id": "825",
"label": "S",
"products": ["1", "2", "3"]
}, {
"id": "840",
"label": "M",
"products": ["3", "4", "5"]
}],
"position": "0"
}
}';
$a = json_decode($variable);
foreach ($a as $item) {
// sorting function
usort($item->options, function($a, $b) { return strcmp($a->label, $b->label); });
}

remove unnecessary hierarchy from json output

I am building an admin backend for an android app. My code provides a json output which the android developer then uses in his app. The developer asked me if it is possible to reduce the hierarchy level in the json output
as in remove the highlighted []0 and put the contents directly inside the []data instead.
This is my current php code
if($type == 1 ) //Handle item display
{
try
{
$query = "SELECT category FROM category";
$result= $DBH->query($query);
while($row = $result->fetch(PDO::FETCH_ASSOC))
{
$cat = $row['category'];
$query1 = "SELECT * FROM item WHERE catagory='$cat'";
$value = $DBH->query($query1);
if($row1 = $value->fetchAll(PDO::FETCH_OBJ)){
$main[] = array('data'=>array($row1));
}
else
{
$main[] = array('data'=>array('catagory'=>$row['category']));
}
}
echo json_encode($main);
$result->closeCursor(); //Close database connection free resources
$DBH = null;
}
catch(PDOException $e){
print $e->getMessage ();
die();
}
}
And the json output being generated
[
{
"data": [
[
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
]
},
{
"data": {
"catagory": "Dinner"
}
},
{
"data": {
"catagory": "Soup"
}
},
{
"data": {
"catagory": "Test"
}
}
]
I am not very sure if I can make the changes he asked or if it is possible. Is it doable?
Your json structure is inconsistent and try this approach, will be easier for the developer to parse
{
"response": [
{
"data": [
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
},
{
"data": [
{
"catagory": "Dinner"
}
]
},
{
"data": [
{
"catagory": "Soup"
}
]
},
{
"data": [
{
"catagory": "Test"
}
]
}
]
}

How to access the JSON's multi-level objects with jQuery [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 9 years ago.
In CodeIgniter, in PHP to create a nested-like elements for dropdown <select> I'am using this function:
function list_categories(&$result, $cats, $sub = ''){ // <- THIS
foreach($cats as $cat){
//$cat['category']->id = $sub.$cat['category']->title;
$result[$cat['category']->id] = $sub.$cat['category']->title; // <- THIS
if( sizeof($cat['children']) > 0 ){
$sub2 = str_replace('—→ ', '–', $sub);
$sub2.= '–→ ';
list_categories($result, $cat['children'], $sub2); // <- THIS
}
}
}
// Make an array available outside the function
$categoryData = array(0 => '-- '.lang('FORM_SELECT_CATTOP').' --');
// Launch the function to fill out the array with nested sets
list_categories($categoryData, $categories);
Which generates the HTML <select> list:
I want to do the same from retrieved JSON in jQuery but can't find the answer to go deeper than first level of JSON objects with this jQuery function:
$.getJSON('../raw_get_categories/'+com_id_selected+'/0', function(data){
var items = [];
$.each(data, function(key, value, sub){
items.push('<option id="'+ key[0] + '">' + value[0] + '</option>');
});
console.log(items);
});
And this is the JSON I want to manage and retrieve the same values from it like in PHP code:
{
"28": {
"category": {
"id": "28", // <<< I need to retrieve THIS
"pid": "0",
"com_id": "2",
"route_id": "59",
"excerpt": "",
"ordering": "1",
"title": "Oblecenie a vybava",
"slug": "oblecenie-a-vybava1",
"description": "",
"image": "clothes.png",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": {
"61": {
"category": {
"id": "61", // <<< I need to retrieve THIS
"pid": "28",
"com_id": "2",
"route_id": "52",
"excerpt": "",
"ordering": "1",
"title": "Ubor na hlavu",
"slug": "ubor-na-hlavu1",
"description": "<p>Capice, Klobuky, Panamy, Baretky, Prilby, Kukly<br></p>",
"image": "clothes-head.png",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
},
"30": {
"category": {
"id": "30",
"pid": "28",
"com_id": "2",
"route_id": "53",
"excerpt": "",
"ordering": "2",
"title": "Bundy a vetrovky",
"slug": "bundy-a-vetrovky",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": {
"34": {
"category": {
"id": "34",
"pid": "30",
"com_id": "2",
"route_id": "0",
"excerpt": "",
"ordering": "0",
"title": "Letne",
"slug": "letne",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
},
"35": {
"category": {
"id": "35",
"pid": "30",
"com_id": "2",
"route_id": "0",
"excerpt": "",
"ordering": "0",
"title": "Vsesezonne",
"slug": "vsesezonne",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
},
"33": {
"category": {
"id": "33",
"pid": "30",
"com_id": "2",
"route_id": "0",
"excerpt": "",
"ordering": "0",
"title": "Zimne",
"slug": "zimne",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
}
}
},
"31": {
"category": {
"id": "31",
"pid": "28",
"com_id": "2",
"route_id": "54",
"excerpt": "",
"ordering": "3",
"title": "Nohavice a teplaky",
"slug": "nohavice-a-teplaky",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
},
"32": {
"category": {
"id": "32",
"pid": "28",
"com_id": "2",
"route_id": "55",
"excerpt": "",
"ordering": "4",
"title": "Obuv",
"slug": "obuv",
"description": "",
"image": "",
"seo_title": "",
"meta": ""
},
"compname": {
"id": "2",
"name": "E-commerce"
},
"children": [ ]
}
}
},
"38": {
...
}
Could someone suggest me the appropriate way to achieve the same foreach statement in jQuery pls?
Juste use point to get more childs
$.getJSON('filename.php', function(data) {
$('#List li').remove();
$.each(data, function(index, item) {
$('#list').append('<li>'+item.category.id+'</li>');
});
});
You can do something like this:
$.each(data.actions, function(entryIndex, entry) {
var html = '<li class="top-level">' + this.action + '</li>';
});
Source

Categories