Sorting only a part of object/array in PHP - 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); });
}

Related

issues when looping throw a json on php

this is driving me nuts,
I'm trying to loop throw a specific json:
I tried using
json_encode -> throws Warning: curl_close() expects parameter 1 to be resource, null given
json_decode -> shows the same text
$json->{"SKU"} and $json->SKU shows the same text
I tried to validate the json with different websites and all say the json is correct
I want to take only this values SKU, price, specialprice (with everything inside) and quantity
[{
"SKU": "118075",
"BrandName": "DIVIDED",
"CategoryName": "Correas",
"Categories": [{
"Id": "423",
"CategoryName": "Moda",
"LevelDepth": "2",
"Parent": null
}, {
"Id": "960",
"CategoryName": "Accesorios de Mujer",
"LevelDepth": "3",
"Parent": "Moda"
}],
"Name": "Divided correa Carrie",
"Description": "a",
"DescriptionShort": "v",
"MetaDescription": "Correa Divided Carrie en presentaci\u00f3n de tres colores.",
"MetaTitle": "Divided Correa Carrie",
"IsPublished": "1",
"PackageWeight": "1.000000",
"Price": 39.9,
"FinalPrice": 16.3,
"SpecialPrice": {
"StartDate": "2014-11-21 06:00:00",
"EndDate": "2017-12-31 23:59:00",
"Reduction": "20.000000",
"ReductionType": "amount"
},
"Quantity": "39",
"DateAdd": "2015-09-24 11:26:08",
"DateUpd": "2016-10-12 12:51:13",
"Images": [{
"Id": "77",
"Cover": "1",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/7\/77.jpg"
}, {
"Id": "78",
"Cover": "0",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/8\/78.jpg"
}, {
"Id": "79",
"Cover": "0",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/9\/79.jpg"
}],
"FlatVariations": [{
"SKU": "001503280",
"Price": 39.9,
"FinalPrice": 16.3,
"Default": "1",
"IdImage": "77",
"Attributes": [{
"Name": "Color",
"Value": "Naranja"
}]
}, {
"SKU": "001503281",
"Price": 39.9,
"FinalPrice": 39.9,
"Default": "0",
"IdImage": "78",
"Attributes": [{
"Name": "Color",
"Value": "Blanco"
}]
}, {
"SKU": "001503282",
"Price": 39.9,
"FinalPrice": 39.9,
"Default": "0",
"IdImage": "79",
"Attributes": [{
"Name": "Color",
"Value": "Negro"
}]
}]
}]
Thanks a lot for any hint (I already tried almost every answer on stack)
I'm pretty sure you can do it in this way:
<?php
//Enter your code here, enjoy!
$text = <<<EOT
[{
"SKU": "118075",
"BrandName": "DIVIDED",
"CategoryName": "Correas",
"Categories": [{
"Id": "423",
"CategoryName": "Moda",
"LevelDepth": "2",
"Parent": null
}, {
"Id": "960",
"CategoryName": "Accesorios de Mujer",
"LevelDepth": "3",
"Parent": "Moda"
}],
"Name": "Divided correa Carrie",
"Description": "a",
"DescriptionShort": "v",
"MetaDescription": "Correa Divided Carrie en presentaci\u00f3n de tres colores.",
"MetaTitle": "Divided Correa Carrie",
"IsPublished": "1",
"PackageWeight": "1.000000",
"Price": 39.9,
"FinalPrice": 16.3,
"SpecialPrice": {
"StartDate": "2014-11-21 06:00:00",
"EndDate": "2017-12-31 23:59:00",
"Reduction": "20.000000",
"ReductionType": "amount"
},
"Quantity": "39",
"DateAdd": "2015-09-24 11:26:08",
"DateUpd": "2016-10-12 12:51:13",
"Images": [{
"Id": "77",
"Cover": "1",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/7\/77.jpg"
}, {
"Id": "78",
"Cover": "0",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/8\/78.jpg"
}, {
"Id": "79",
"Cover": "0",
"Legend": "Divided correa Carrie",
"url": "https:\/\/www.google.com.pe\/img\/p\/7\/9\/79.jpg"
}],
"FlatVariations": [{
"SKU": "001503280",
"Price": 39.9,
"FinalPrice": 16.3,
"Default": "1",
"IdImage": "77",
"Attributes": [{
"Name": "Color",
"Value": "Naranja"
}]
}, {
"SKU": "001503281",
"Price": 39.9,
"FinalPrice": 39.9,
"Default": "0",
"IdImage": "78",
"Attributes": [{
"Name": "Color",
"Value": "Blanco"
}]
}, {
"SKU": "001503282",
"Price": 39.9,
"FinalPrice": 39.9,
"Default": "0",
"IdImage": "79",
"Attributes": [{
"Name": "Color",
"Value": "Negro"
}]
}]
}]
EOT;
$decoded = json_decode($text);
# Index 0 because is an array
var_dump($decoded[0]->SKU);
You can execute the code directly here.
Hope this helps.

Obtaining the last level of a json tree on php

I have a json tree with categories,
I would like to obtain the last level of elements for each different category.
For example on this json:
[
{
"category_id": "3",
"parent_id": "2",
"name": "Women",
"categories": [
{
"category_id": "11",
"parent_id": "3",
"name": "Clothing",
"categories": [
{
"category_id": "30",
"parent_id": "11",
"name": "T-shirts",
"categories": null
},
{
"category_id": "33",
"parent_id": "11",
"name": "jeans",
"categories": null
}
]
}
]
},
{
"category_id": "5",
"parent_id": "2",
"name": "Footwear ",
"categories": [
{
"category_id": "15",
"parent_id": "5",
"name": "Rings",
"categories": [
{
"category_id": "51",
"parent_id": "15",
"name": "Small Leathers",
"categories": null
}
]
},
{
"category_id": "16",
"parent_id": "5",
"name": "Bands",
"categories": [
{
"category_id": "41",
"parent_id": "16",
"name": "boots",
"categories": null
}
]
},
{
"category_id": "48",
"parent_id": "5",
"name": "Bracelets",
"categories": [
{
"category_id": "55",
"parent_id": "48",
"name": "Cocktail",
"categories": null
}
]
}
]
}
]
The result would be an array (T-shirts, Jeans, Small Leathers, boots, cocktail)
What I was thinking is to decode it on an array and search filter the array with all the categories that are null, but I'm not sure if it's the best option because the object have different levels.
(I'm sorry for the English)
Json string is not a valid. It can be made valid by enclosing the json string in {}.
$json = '{"categories": [
{
"category_id": "3",
"parent_id": "2",
"name": "Women",
"categories": [
{
"category_id": "11",
"parent_id": "3",
"name": "Clothing",
"categories": [
{
"category_id": "30",
"parent_id": "11",
"name": "T-shirts",
"categories": null
},
{
"category_id": "33",
"parent_id": "11",
"name": "jeans",
"categories": null
}
]
}
]
},
{
"category_id": "5",
"parent_id": "2",
"name": "Footwear ",
"categories": [
{
"category_id": "15",
"parent_id": "5",
"name": "Rings",
"categories": [
{
"category_id": "51",
"parent_id": "15",
"name": "Small Leathers",
"categories": null
}
]
},
{
"category_id": "16",
"parent_id": "5",
"name": "Bands",
"categories": [
{
"category_id": "41",
"parent_id": "16",
"name": "boots",
"categories": null
}
]
},
{
"category_id": "48",
"parent_id": "5",
"name": "Bracelets",
"categories": [
{
"category_id": "55",
"parent_id": "48",
"name": "Cocktail",
"categories": null
}
]
}
]
}
]}';
Decode the json string in to php opject
$json_object = json_decode($json);
Use this recursive function to fetch get all the last level categories in a array.
function getLastCategories($object){
$last_categories = array();
if(is_array($object->categories)){
foreach($object->categories as $categories){
$last_categories = array_merge( $last_categories, getLastCategories($categories));
}
}else{
$last_categories[]=$object->name;
}
return $last_categories;
}
print_r(getLastCategories($json_object));
Output:
Array
(
[0] => T-shirts
[1] => jeans
[2] => Small Leathers
[3] => boots
[4] => Cocktail
)
You can do this using recursive iterators.
$categories = json_decode($json);
// create the iterator
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($categories));
// iterate recursively
foreach ($iterator as $key => $subcategories) {
// if the 'categories' key is empty for the current level...
if ($key == 'categories' && !$subcategories) {
// then add the value of the 'name' key for the current level to your result array.
$result[] = $iterator->getSubIterator()->offsetGet('name');
}
}
This may not be the most efficient way to do it, but it makes the code pretty simple.

Extracting values from JSON data

I have the JSON data given below. The 'crop' array contains multiple array of crop price, I want to get average crop price of all districts(using 'district_id').
<i>{
"status": "ok",
"count": 7,
"crop": [
{
"id": "133",
"crop_id": "81",
"price": "45.00",
"description": null,
"user_id": "27",
"block_id": "1",
"longitude": "87.8661808",
"latitude": "23.2340073",
"date": "2014-02-03",
"time": "12:44:43",
"district_id": "1"
},
{
"id": "135",
"crop_id": "81",
"price": "10.50",
"description": null,
"user_id": "27",
"block_id": "1",
"longitude": "87.8662402",
"latitude": "23.2339822",
"date": "2014-02-03",
"time": "12:44:54",
"district_id": "1"
},
{
"id": "143",
"crop_id": "81",
"price": "35",
"description": null,
"user_id": "27",
"block_id": "1",
"longitude": "0.0",
"latitude": "0.0",
"date": "2014-02-03",
"time": "13:12:50",
"district_id": "1"
},
{
"id": "146",
"crop_id": "81",
"price": "85",
"description": null,
"user_id": "27",
"block_id": "1",
"longitude": "0.0",
"latitude": "0.0",
"date": "2014-02-03",
"time": "14:29:07",
"district_id": "1"
},
{
"id": "148",
"crop_id": "81",
"price": "25",
"description": null,
"user_id": "27",
"block_id": "1",
"longitude": "0.0",
"latitude": "0.0",
"date": "2014-02-03",
"time": "14:58:01",
"district_id": "1"
},
{
"id": "132",
"crop_id": "81",
"price": "10",
"description": null,
"user_id": "119",
"block_id": "34",
"longitude": "0.0",
"latitude": "0.0",
"date": "2014-02-03",
"time": "12:41:49",
"district_id": "4"
},
{
"id": "134",
"crop_id": "81",
"price": "12",
"description": null,
"user_id": "119",
"block_id": "34",
"longitude": "0.0",
"latitude": "0.0",
"date": "2014-02-03",
"time": "12:43:50",
"district_id": "4"
}
]
}</i>
Use json_decode method to convert it to an std_class or use the 2nd parameter of this method to convert it to an associated array.
Take a look at http://in1.php.net/json_decode
Once you decode it, you can easily access the variables like accessing properties of a class or as an array object if you are converting to an associated array
First you have too decode the JSON using json_decode function, then access using variables.
Do like this..
//Assign your JSON data to this $json variable as shown in the demo.
$arr = json_decode($json,1);
foreach($arr['crop'] as $arr1)
{
foreach($arr1 as $k=>$v)
{
if($arr1['district_id']==1)
{
$avgpr[] = $arr1['price'];
}
}
}
echo $avgprice = array_sum($avgpr)/count($avgpr);
OUTPUT :
40.1
Demo

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

Issue with json_decode and json_encode - it adds keys to original JSON

I have this JSON string:
{
"product": [
{
"id": "1",
"title": "producta",
"size": "50",
"weight": "1000",
"price": "30",
"quantity": "100",
"cartID": "1"
},
{
"id": "1",
"title": "producta",
"size": "50",
"weight": "1000",
"price": "30",
"quantity": "100",
"cartID": "2"
}
]
}
When I use the PHP function json_decode($products, true), and then I re-encode it using json_encode($products), the string becomes this:
{
"product": {
"1": {
"id": "2",
"title": "producta",
"size": "50",
"weight": "1000",
"price": "30",
"quantity": "100",
"cartID": "2"
},
"2": {
"id": "1",
"title": "producta",
"size": "50",
"weight": "1000",
"price": "30",
"quantity": "100",
"cartID": "3"
}
}
}
After decoding and re-encoding, it adds a key to every "product"
Is there a way around this?
Posting this here since it'd be too ugly in a comment, but this is what I get on PHP 5.3.6 after doing a echo json_encode(json_decode('...your json...', true));:
{"product": [
{"id":"1","title":"producta","size":"50","weight":"1000","price":"30","quantity":"100","cartID":"1"},
{"id":"1","title":"producta","size":"50","weight":"1000","price":"30","quantity":"100","cartID":"2"}
]}
Note the lack of extra keys. Are you doing any manipulations on the decoed array before re-encoding?
You are probably using mysqli_fetch_array instead of mysqli_fetch_assoc. Meaning u are json decoding a key arreay instead of an associative array

Categories