sort json results in foreach loop - php

I am running a foreach loop to display json results, when certain conditions are met, and would like to sort them by the name field. I am trying usort(), but can't seem to figure it out.
JSON:
{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg",
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg",
}
}
PHP:
$data_json = file_get_contents('data.json');
$data_array = json_decode($data_json, true);
$i = 0;
foreach($data_array as $key => $person){
if($person['title'] == 'some title'){
include('card.php');
if(++$i % 4 === 0) {
echo '<div class="clearfix"></div>'; // inserts a clearfix every 4 cards
}
}
}
So this returns the all the results I expect, but not sorted. I've tried usort() a few different ways, but just fell on my face terribly:) Please help!

use json_decode first to convert to php array, set the flag to TRUE for associative array $myarr = json_decode($array, TRUE)
the try custom usort
// Sort the multidimensional array
usort($myarr, "custom_sort");
// Define the custom sort function
function custom_sort($a,$b) {
return $a['name']>$b['name'];
}
I hope this helps.

Your json is improperly formatted. There's a couple extra commas, one after each JPG item. Removed below.
Then, json_decode the json string to a PHP associative array, and, since you're using the names as json indexes, ksort (key sort) the resulting array.
$json_string = '{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg"
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg"
}
}';
$data_array = json_decode($json_string, true);
ksort($data_array);
// the remaining code
A print_r after the ksort displays:
Array
(
[Another Name] => Array
(
[name] => Another Name
[title] => Title is here
[photo_url] => Person.jpg
)
[Shawn Taylor] => Array
(
[name] => Shawn Taylor
[title] =>
[photo_url] => house_165 (1).jpg
)
)
If you need to sort by a nested index, and you want to maintain the associative array, use uasort:
uasort($data_array, 'sort_name_index');
function sort_name_index($a, $b) {
return $a['name'] > $b['name'];
}

Related

Merging 2 arrays based on a relational array

I have the following arrays:
$excel_arr = array(
["C1", "Title 3"],
["A1", "Title 1"],
["B1", "Title 2"],
["D1", "Title 4"]
);
$db_result = array(
"title_2" => "Cell 2 Value",
"title_1" => "Cell 1 Value",
"title_3" => "Cell 3 Value",
"title_5" => "Cell 5 Value"
);
$excel_db_relation = array(
"title_1" => "Title 1",
"title_2" => "Title 2",
"title_3" => "Title 3",
"title_4" => "Title 4",
"title_5" => "Title 5"
);
usort($excel_arr, function ($a, $b) { return strnatcmp($a[0], $b[0]); });
$excel_arr is an array with the titles for each column in an excel file. The first cell defines the cell coordinate and the second the actual cell value.
$db_result is an array containing queried values from a database. The key is column name in the table.
$excel_db_relation is an array which defines the relation between the 2 former arrays. Which excel column is linked to which db table column. In this example they are very similar, but in practice there might be more than just an underscore that differs.
The cell coordinates in $excel_arr defines the order in which each value must be printed. To do this I sort the array with the usort() as seen above.
I need to somehow merge these arrays so that the resulting array becomes:
array("Title 1" => "Cell 1 Value", "Title 2" => "Cell 2 Value", "Title 3" => "Cell 3 Value")
The database array didn't return a value for cell 4 and the excel sheet doesn't define a E5 cell. So these must not be included in the resulting array.
I have tried array_merge($excel_db_relation, $db_result) and various combinations of array_merge() and array_flip() but no matter what I do I can't seem to merge the arrays with "Title X" being the key.
The solution using array_intersect_key, array_intersect and array_column functions:
$result = [];
// getting concurrent 'titles'(by key)
$titles = array_intersect_key($excel_db_relation, $db_result);
foreach (array_intersect($titles, array_column($excel_arr, 1)) as $k => $v) {
$result[$v] = $db_result[$k];
}
print_r($result);
The output:
Array
(
[Title 1] => Cell 1 Value
[Title 2] => Cell 2 Value
[Title 3] => Cell 3 Value
)
Update:
Alternative approach to hold the order in which each value must be printed. Used functions: array_merge_recursive(to combine cell titles and values into separate groups) and array_column functions:
$result = [];
$bindings = array_column(array_merge_recursive($db_result, $excel_db_relation), 0, 1);
foreach (array_column($excel_arr, 1) as $title) {
if (isset($bindings[$title])) $result[$title] = $bindings[$title];
}
print_r($result);
The output:
Array
(
[Title 3] => Cell 3 Value
[Title 1] => Cell 1 Value
[Title 2] => Cell 2 Value
)
Try this:
$result = array_flip($excel_db_relation);
array_walk($result, function(&$value, $key) use ($db_result) {
$value = $db_result[$value];
});
var_dump($result);
But make sure that all keys exist beforehand.
This worked for me:
<?php
//...
usort($excel_arr, function ($a, $b) { return strnatcmp($a[0], $b[0]); });
$result = [];
// traverse the *title* column in the sorted $excel_arr
foreach (array_column($excel_arr, 1) as $a) {
// could use array_flip to speed up this test, though
// this can be problematic if the values aren't *good* array keys
$k = array_search($a, $excel_db_relation);
// if there is a key and it also exists in $db_result
if (false !== $k && array_key_exists($k, $db_result)) {
// assign it to the final result
$result[$a] = $db_result[$k];
}
}
print_r($result);

how do I get my php array to json

I'm trying to make my json output in the following format below, but I do not know how to code it to make it display in just format... I just have the values, any kind of help I can get on this is greatly appreciated!
{
"firstcolumn":"56036",
"loc":"Deli",
"lastA":"Activity",
"mTime":"2011-02-01 11:59:26.243",
"nTime":"2011-02-01 10:57:02.0",
"Time":"2011-02-01 10:57:02.0",
"Age":"9867 Hour(s)",
"ction":" ",
"nTime":null
},
{
"firstcolumn":"56036",
"loc":"Deli",
"lastA":"Activity",
"mTime":"2011-02-01 11:59:26.243",
"nTime":"2011-02-01 10:57:02.0",
"Time":"2011-02-01 10:57:02.0",
"Age":"9867 Hour(s)",
"ction":" ",
"nTime":null
}
You can use a PHP associative array to set the key => value's of your array to be converted to json. As you would expect the key of the php associative array becomes the key of the JSON object, and the same with the values.
$array = array(
'firstcolumn' => '56036',
"loc" => "Deli",
"lastA" => "Activity",
"mTime" => "2011-02-01 11:59:26.243",
"nTime" => "2011-02-01 10:57:02.0",
"Time" => "2011-02-01 10:57:02.0",
"Age" => "9867 Hour(s)",
"ction" => "",
"nTime" => NULL
);
You can do both arrays like this (using previous array to show concept but can replace with that same array())
$array2 = $array1;
$array2['firstcolumn'] = "56037";
$botharrays = array($array, $array2);
What we just did is put both sub arrays into one containing array so that when you encode the json it has each object separately.
array( array1, array2 )
Then use json_encode() to encode the array into the json format you requested
$JSON= json_encode($array);
or
$json = json_encode($botharrays);
I think you are looking for this:
$json = json_encode($myArray);
print_r($json);

Searching JSON PHP

I have JSON that looks like this (shortened for readability):
{
"heroes": [
{
"name": "antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
{
"name": "axe",
"id": 2,
"localized_name": "Axe"
},
{
"name": "bane",
"id": 3,
"localized_name": "Bane"
}
]
}
I have a PHP variable that is equal to one of the three ids. I need to search the JSON for the id and return the localized name. This is what I’m trying so far.
$heroid = $myplayer['hero_id'];
$heroes = file_get_contents("data/heroes.json");
$heroesarray = json_decode($heroes, true);
foreach ($heroesarray as $parsed_key => $parsed_value) {
if ($parsed_value['id'] == $heroid) {
$heroname = $parsed_value['localized_name'];
}
}
Easy. Just use json_decode(). Explanation follows the code at the bottom.
// First set the ID you want to look for.
$the_id_you_want = 2;
// Next set the $json.
$json = <<<EOT
{
"heroes": [
{
"name": "antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
{
"name": "axe",
"id": 2,
"localized_name": "Axe"
},
{
"name": "bane",
"id": 3,
"localized_name": "Bane"
}
]
}
EOT;
// Now decode the json & return it as an array with the `true` parameter.
$decoded = json_decode($json, true);
// Set to 'TRUE' for testing & seeing what is actually being decoded.
if (FALSE) {
echo '<pre>';
print_r($decoded);
echo '</pre>';
}
// Now roll through the decoded json via a foreach loop.
foreach ($decoded as $decoded_array_key => $decoded_array_value) {
// Since this json is an array in another array, we need anothe foreach loop.
foreach ($decoded_array_value as $decoded_key => $decoded_value) {
// Do a comparison between the `$decoded_value['id']` and $the_id_you_want
if ($decoded_value['id'] == $the_id_you_want) {
echo $decoded_value['localized_name'];
}
}
}
Okay, the reason my first try at this did not work—and neither did yours—is your JSON structure was nested one more level deep that what is expected. See the debugging code I have in place with print_r($decoded);? This is the output when decoded as an array:
Array
(
[heroes] => Array
(
[0] => Array
(
[name] => antimage
[id] => 1
[localized_name] => Anti-Mage
)
[1] => Array
(
[name] => axe
[id] => 2
[localized_name] => Axe
)
[2] => Array
(
[name] => bane
[id] => 3
[localized_name] => Bane
)
)
)
First you have an array to begin with which could equate to $decoded[0] and then below that you have another array that equates to $decoded[0]['heroes'] and then in there is the array that contains the values which is structured as $decoded[0]['heroes'][0], $decoded[0]['heroes'][1], $decoded[0]['heroes'][2].
But the key to solving this was the print_r($decoded); which helped me see the larger structure of your JSON.
json_decode() takes a JSON string and (if the second parameter is true) turns it into an associate array. We then loop through this data with a foreach until we find the hero you want.
$json = ''; // JSON string
$data = json_decode($json, true);
foreach($data['heroes'] as $hero) {
if($hero['id'] === 2) {
var_dump($hero['localized_name']);
// Axe
// This will stop the loop, if you want to keep going remove this line
break;
}
}

PHP: create an array from values in two arrays based on matching keys

The Problem
I would like to create a new associative array with respective values from two arrays where the keys from each array match.
For example:
// first (data) array:
["key1" => "value 1", "key2" => "value 2", "key3" => "value 3"];
// second (map) array:
["key1" => "map1", "key3" => "map3"];
// resulting (combined) array:
["map1" => "value 1", "map3" => "value 3"];
What I've Tried
$combined = array();
foreach ($data as $key => $value) {
if (array_key_exists($key, $map)) {
$combined[$map[$key]] = $value;
}
}
The Question
Is there a way to do this using native PHP functions? Ideally one that is not more convoluted than the code above...
This question is similar to Combining arrays based on keys from another array. But not exact.
It's also not as simple as using array_merge() and/or array_combine(). Note the arrays are not necessarily equally in length.
You can use array_intersect_key() (http://ca2.php.net/manual/en/function.array-intersect-key.php).
Something like that:
$int = array_intersect_key($map, $data);
$combined = array_combine(array_values($map), array_values($int));
Also it would be a good idea ksort() both $map and $data.

Create an object from a valid JSON array with php

I know my JSON is valid, I'm wanting to pull all the KEY's out of the array and put them in an object. However it seems I can either access ONE objects Key or Value, the entire array, or one key value pair. I have not figured out how to parse out all the keys, or all the values in the array.
Here is what I've tried:
print_r($json_obj) yields:
Array ( [0] => Array ( [0] => uploads/featured/doublewm-4097.jpg [1] => featured ) [1] => Array ( [0] => uploads/featured/moon-5469.jpg [1] => featured ) )
print_r($json_obj[0][1]) yields:
featured
print_r($json_obj[1][0]) yields:
uploads/featured/moon-5469.jpg
print_r($json_obj[1][1]) yeilds:
featured
print_r($json_obj[0][0]) yields:
uploads/featured/doublewm-4097.jpg
PHP Code:
<?php
$resultSet = '[["uploads/featured/doublewm-4097.jpg","featured"],
["uploads/featured/moon-5469.jpg","featured"]]';
$json_obj = json_decode($resultSet);
// print_r($json_obj);
print_r($json_obj[0][1]);
?>
The JSON validates per JSONLint
[
[
"uploads/featured/doublewm-4097.jpg",
"featured"
],
[
"uploads/featured/moon-5469.jpg",
"featured"
]
]
I would like to end up with a object with all the keys in the json_obj... ie:
json_obj = array(
'uploads/featured/moon-5469.jpg',
'uploads/featured/doublewm-4097.jpg'
);
If your input is always in the same format, you can handle it like this
$tmp = json_decode($resultSet);
$json_obj = array();
foreach ($tmp as $values) {
array_push($json_obj, $values[0]);
}
This will give you $json_obj in the desired format with a hardcoded $resultSet like the one you provided.
maybe this is what you are looking for:
json encode server-side like:
echo json_encode($html);
json parse clientside like
var str = JSON.parse(data);
alert (JSON.stringify(str))
I managed to fix it like this:
Changing the json object to this format
data = { gallery: gallery_name,
files: [
// imagefile,imagefile,imagefile...
]
};
And the using the following php
$resultSet = json_decode($_GET['submittedResults'], true);
$gallery = $resultSet['gallery'];
$files_to_zip = $resultSet['files'];

Categories