I have a JSON array like this
$countries = [
{
"id": "1",
"country_name": "Afghanistan",
},
{
"id": "2",
"country_name": "Albania",
},
{
"id": "3",
"country_name": "Algeria",
},
{
"id": "4",
"country_name": "American Samoa",
}
..
..
..
{
"id": "50",
"country_name": "Zimbabwe",
}
];
The following array contains, the list of countries that I need to sort to top
$top_countries = ['United States', 'United Kingdom', 'German'];
What is the best way to sort the above array as follows
$countries = [
{
"id": "30",
"country_name": "United States",
},
{
"id": "31",
"country_name": "United Kingdom",
},
{
"id": "20",
"country_name": "German",
},
{
"id": "1",
"country_name": "Afghanistan",
},
{
"id": "2",
"country_name": "Albania",
},
{
"id": "3",
"country_name": "Algeria",
},
{
"id": "4",
"country_name": "American Samoa",
}
..
..
..
{
"id": "50",
"country_name": "Zimbabwe",
}
];
// index "value" of country by name
$top = array_flip($top_countries);
usort($countries, function($a, $b) use ($top) {
// get "value" for each country, if it is in index
$aValue = isset($top[$a->country_name])?$top[$a->country_name]:-1;
$bValue = isset($top[$b->country_name])?$top[$b->country_name]:-1;
if ($aValue == $bValue) {
// preserve "original order", assuming they were ordered by id
return $a->id < $b->id ? -1 : 1;
}
return $aValue < $bValue ? 1:-1;
});
Related
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;
}
I am working on the array to JSON object code and want the output using json_encode method.
here is the code
foreach($servicecategory as $servicecategory1) {
$getcat = $objcat->Get_Category($servicecategory1);
$employee = array(
'category_id'=>mysql_real_escape_string($getcat['id']),
'category_name'=>mysql_real_escape_string($getcat['catname']),
'category_image_url'=>"",
'subcategory'=>array()
);
$getsubcat = $objcat->getCategoriesAdminNew($servicecategory1);
foreach($getsubcat as $getsubcat1) {
$getcat = $objcat->Get_Category($getsubcat1['id']);
$employee['subcategory'][]= array(
'category_id'=>mysql_real_escape_string($getcat['id']),
'category_name'=>mysql_real_escape_string($getcat['catname']),
'vendor_products_details' =>array()
);
$getproduct = $objuser->VendorProductDetailsNew2($userinfo['profile_id'],$getcat['id']);
foreach($getproduct as $getproducts){
$getcat = $objcat->Get_Category($getproducts['subcat_id']);
$employee['vendor_products_details'][] = array(
'product_id' => $getproducts['id'],
'product_name' => $getproducts['pname'],
'Price' => $getproducts['price'],
);
}
}
$data[] = $employee;
}
if($userinfo!='') {
$infodatas=array("status"=>"success","vendor_detail"=> array($array1, $data));
$ress=json_encode($infodatas);
echo $ress ;
}
it displays the output like below, which is not the proper format for json out put.
{
"category_id": "1",
"category_name": "Dry Cleaning",
"category_image_url":"",
"subcategory": [
{
"sub_category_id": "4",
"sub_category_name": "Men",
"vendor_products_details": [
]
},
{
"sub_category_id": "5",
"sub_category_name": "Women",
"vendor_products_details": [
]
}
],
"vendor_products_details": [
{
"product_id": "19",
"product_name": "T Shirt",
"Price": "20"
},
{
"product_id": "20",
"product_name": "Top",
"Price": "15"
}
]
},
But I want the output in below format using multiple for each loop.
{
"category_id": "1",
"category_name": "Dry Cleaning",
"category_image_url": "",
"subcategory": [
{
"sub_category_id": "4",
"sub_category_name": "Men",
"vendor_products_details": [
{
"product_id": "19",
"product_name": "T Shirt",
"Price": "20"
},
{
"product_id": "20",
"product_name": "Top",
"Price": "15"
}
]
},
{
"sub_category_id": "5",
"sub_category_name": "Men",
"vendor_products_details": "Women",
"vendor_products_details": [
{
"product_id": "18",
"product_name": "T shirt",
"Price": "15"
},
{
"product_id": "9",
"product_name": "Bedsheet",
"Price": "15"
}
]
}
]
},
same for each main category
Your current foreachloop states that in the get products section it should be added to $employee['vendor_products_details'][], but your explanation states that you want the products to be under your subcategory. This can be achieved by 2 small changes:
foreach($getsubcat as $getsubcat1) {
$getcat = $objcat->Get_Category($getsubcat1['id']);
$employee['subcategory'][$getsubcat1['id']]= array(
'category_id'=>mysql_real_escape_string($getcat['id']),
'category_name'=>mysql_real_escape_string($getcat['catname']),
'vendor_products_details' =>array()
);
$getproduct = $objuser->VendorProductDetailsNew2($userinfo['profile_id'],$getcat['id']);
foreach($getproduct as $getproducts){
$getcat = $objcat->Get_Category($getproducts['subcat_id']);
$employee['subcategory'][$getsubcat1['id']]['vendor_products_details'][] = array(
'product_id' => $getproducts['id'],
'product_name' => $getproducts['pname'],
'Price' => $getproducts['price'],
);
}
}
What is changed:
In your foreachloop with $getsubcat you need to changed the array to:
$employee['subcategory'][$getsubcat1['id']]= array(............);
In your foreachloop with $getproduct you need to change the array to:
$employee['subcategory'][$getsubcat1['id']]['vendor_products_details'][] = array(............);
Doing it this way you vendor product details will be nested in your subcategory with the id used in that specific loop.
I have a number of JSON such as:
ITEM 1:
{
"countries_views": [
{
"thecount": "563",
"country": "Greece"
},
{
"thecount": "48",
"country": "United States"
},
{
"thecount": "11",
"country": "Luxembourg"
},
{
"thecount": "7",
"country": "Germany"
},
{
"thecount": "6",
"country": "Cyprus"
},
{
"thecount": "2",
"country": "India"
},
{
"thecount": "2",
"country": "France"
},
{
"thecount": "2",
"country": "United Kingdom"
},
{
"thecount": "1",
"country": "Nigeria"
},
{
"thecount": "1",
"country": "Russia"
}
]
}
ITEM 2:
{
"countries_views": [
{
"thecount": "1037",
"country": "Greece"
},
{
"thecount": "17",
"country": "United States"
},
{
"thecount": "17",
"country": "Cyprus"
},
{
"thecount": "12",
"country": "Germany"
},
{
"thecount": "11",
"country": ""
},
{
"thecount": "4",
"country": "United Kingdom"
},
{
"thecount": "4",
"country": "Australia"
},
{
"thecount": "2",
"country": "Belgium"
},
{
"thecount": "1",
"country": "Russia"
},
{
"thecount": "1",
"country": "Argentina"
}
]
}
And so on! What i need to do is Combine/Merge this Data in 1 array with PHP and i need to add the values of Duplicates. The end result should look something like this:
{
"countries_views": [
{
"thecount": "**1600**",
"country": "Greece"
},
{
"thecount": "**65**",
"country": "United States"
},
etcetcetc
]
}
First parse the JSON data, and we just traverse the array to find the duplicates and add them up.
<?php
// emit the code of parsing json. (see function json_decode)
$arr1 = [
(object)['thecount' => 563, 'country' => 'Greece'],
(object)['thecount' => 12, 'country' => 'US'],
(object)['thecount' => 15, 'country' => 'UK'],
];
$arr2 = [
(object)['thecount' => 1563, 'country' => 'Greece'],
(object)['thecount' => 152, 'country' => 'CN'],
];
foreach ($arr1 as $each) {
$exists = false;
foreach ($arr2 as &$e) {
if ($e->country == $each->country) {
$e->thecount += $each->thecount;
$exists = true;
}
}
if (!$exists) {
array_push($arr2, $each);
}
}
$res = $arr2;
var_dump($res);
Here is how to get $arr1, $arr2, in your example.
<?php
$arr1_obj = json_decode($item1);
$arr2_obj = json_decode($item2);
$arr1 = $arr1_obj->countries_views;
$arr2 = $arr2_obj->countries_views;
I am trying to iterate both index of JSON(Players and Buildings), so that i can a get new result in jQuery
I have two index of JSON one having information of Players and second index having information of Building related Player.
I want to Parse it so that i can get Player and its building name.
My Actual JSON result
{
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
}
Need this
"information": [
{
"player_id": "35",
"Buildings_name": "ABC"
},
{
"player_id": "36",
"Buildings_name": "DEF"
},
{
"player_id": "37",
"Buildings_name": "GHI"
},
{
"player_id": "38",
"Buildings_name": "JKL"
}
]
}
Here you go, this go for each player and check if there are buildings and will map them to new structure. This will not filter values for buildings that do not have mapping to players, and will not include the buildings with no players.
var x = {
"Players": [
{
"id": "35",
"building_id": "8",
"room_num": "101",
},
{
"id": "36",
"building_id": "9",
"room_num": "102",
},
{
"id": "37",
"building_id": "10",
"room_num": "103",
},
{
"id": "38",
"building_id": "11",
"room_num": "104",
}
],
"Buildings": [
{
"id": "8",
"name": "ABC"
},
{
"id": "9",
"name": "DEF"
},
{
"id": "10",
"name": "GHI"
},
{
"id": "11",
"name": "JKL"
}
]
};
var res = $.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
})
and if you want to filter values that do not have relationships e.g INNER join
var resInnerJoin = $.grep($.map(x.Players, function(item) {
return {
player_id: item.id,
building_name: $.grep(x.Buildings, function(i) {
return i.id == item.building_id
}).length != 0 ? $.grep(x.Buildings, function(i) {
return i.id == item.building_id
})[0].name : undefined
}
}), function(it) {
return it.building_name != undefined
})
If you need it in PHP :
$json = '{...}';
// create and PHP array with you json data.
$array = json_decode($json, true);
// make an array with buildings informations and with building id as key
$buildings = array();
foreach( $array['Buildings'] as $b ) $buildings[$b['id']] = $b;
$informations = array();
for ( $i = 0 ; $i < count($array['Players']) ; $i++ )
{
$informations[$i] = array(
'player_id' => $array['Players'][$i]['id'],
'Buildings_name' => $buildings[$array['Players'][$i]['building_id']]['name']
);
}
$informations = json_encode($informations);
var_dump($informations);
I'm generating the following array in json format
[
{
"country": "China",
"amount": "1"
},
{
"country": "India",
"amount": "5"
},
{
"country": "India",
"amount": "317"
},
{
"country": "India",
"amount": "8"
},
{
"country": "India",
"amount": "2"
},
{
"country": "United States",
"amount": "213"
},
{
"country": "Iceland",
"amount": "263"
}
]
I've tried merging them with the following code
$newData = array();
$result = array_reduce(
$data,
function($newData, $value) {
$key = $value['country'];
if (!isset($newData[$key])) {
$newData[$key] = $value;
} else {
$newData[$key]['amount'] += $value['amount'];
}
return $newData;
},
$newData
);
my desired output is
[
{
"country": "China",
"amount": "1"
},
{
"country": "India",
"amount": "332"
},
{
"country": "United States",
"amount": "213"
},
{
"country": "Iceland",
"amount": "263"
}
]
As you can see the array is merged with all the country values grouped and the amount values added accordingly.
Use a simple foreach loop rather than array_reduce.
$newData = array();
foreach ($data as $e) {
if (isset($newData[$e['country']])) {
$newData[$e['country']]['amount'] += $e['amount'];
} else {
$newData[$e['country']] = $e;
}
}
$newData = array_values($newData);
Try this:
$newData = array();
foreach($oldData as $oldEntry){
foreach($newData as $newEntry){
if($oldEntry['country'] == $newEntry['country'])
$newEntry['country'] += $oldEntry['country'];
break;
}
$newData[] = array('country' => $oldEntry['country'], 'amount' => $oldEntry['amount'];
}