How do I sort a PHP array by an element nested inside?
You can use usort
as:
function cmp($a, $b) {
return $a['weight'] - $b['weight'];
}
usort($arr,"cmp");
PHP sort 2d array alphabetically by nested value
You should use usort() (i'm assuming PHP 5.3+ here):
usort($your_array, function ($elem1, $elem2) {
return strcmp($elem1['title'], $elem2['title']);
});
Edit: I hadn't noticed you wanted to preserve index association, so you actually need to use
uasort()
instead, with the same parameters.Edit2:
Here is the pre-PHP 5.3 version:
function compareElems($elem1, $elem2) {
return strcmp($elem1['title'], $elem2['title']);
}
uasort($your_array, "compareElems");
How do I sort by nested php array
I dont understand half of that code (what's all the regex for?), but to achieve desired sorted table you can simply do:
$profile = simplexml_load_file('http://andrewfinden.com/test/feed.xml');
$productions = $profile->xpath(
'/profile/repertoire/composer/work/role/production'
);
to load the XML and get the list of all productions as they appear in the XML. To sort them you can use a custom sort:usort($productions, function($a, $b) {
return $b['startdate'] - $a['startdate'];
});
which will compare the startdates of the simplexml elements and sort them in descending order. And then it's only a matter of just iterating the productions:<table>
<thead>
<tr>
<th>Year</th>
<th>Company</th>
</tr>
</thead>
<tbody>
<?php foreach ($productions as $production): ?>
<tr>
<td><?php echo htmlspecialchars($production['startdate'])?></td>
<td><?php echo htmlspecialchars($production['company'])?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
See demoAlso see this demo for your additional requests in chat, e.g. limit productions to those with a review and sorting works by production startdate.
How to Sort a Multi-dimensional Array by Value
Try a usort. If you are still on PHP 5.2 or earlier, you'll have to define a sorting function first:
function sortByOrder($a, $b) {
return $a['order'] - $b['order'];
}
usort($myArray, 'sortByOrder');
Starting in PHP 5.3, you can use an anonymous function:usort($myArray, function($a, $b) {
return $a['order'] - $b['order'];
});
With PHP 7 you can use the spaceship operator:usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
});
Finally, in PHP 7.4 you can clean up a bit with an arrow function:usort($myArray, fn($a, $b) => $a['order'] <=> $b['order']);
To extend this to multi-dimensional sorting, reference the second/third sorting elements if the first is zero - best explained below. You can also use this for sorting on sub-elements.usort($myArray, function($a, $b) {
$retval = $a['order'] <=> $b['order'];
if ($retval == 0) {
$retval = $a['suborder'] <=> $b['suborder'];
if ($retval == 0) {
$retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];
}
}
return $retval;
});
If you need to retain key associations, use uasort()
- see comparison of array sorting functions in the manual. Sort 2nd nested array by value in 3rd with php
Try with array_map to get into the nested elements and your Start Time
has a 'T' character which I think cannot be used with strtotime
so I've removed it:
function custom_map( $array ) {
usort( $array, function( $a, $b ) {
return ($a['Start Time']<$b['Start Time'])? -1 : 1;
});
return $array;
}
$new_array = array_map( "custom_map", $week_schedule );
var_dump($new_array);
DemoExplanation:
Since you were interested in learning how this works, I did a few research myself and came up with this explanation:First of all, you should know what array_map() and usort() are for.
array_map() from PHP Doc:
Syntax:array_map() returns an array containing all the elements of array1
after applying the callback function to each one.
array array_map ( callable $callback , array $array1 [, array $... ] )
In simple words, array_map() will pass each element of your array to the callback function that you specify. And it returns an array (with the changed values, that you have done in that callback function).Now usort(),
usort() from PHP Doc:
Syntax:This function will sort an array by its values using a user-supplied comparison function. If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function.
bool usort ( array &$array , callable $value_compare_func )
So, usort() basically compares each array element in order to sort it in the correct order. The line that you see here:return ($a['Start Time']<$b['Start Time'])? -1 : 1;
basically translates as: if $a['Start Time'] is lesser than $b['Start Time'], then return -1 so
that $a can come before $b
with values:$a['Start Time'] = '1899-12-30T09:00:00'; //3rd element
$b['Start Time'] = '1899-12-30T17:00:00'; //1st element
Now clearly, $a which is the third element is lesser than the 1st element $b, thus $a will be positioned before it. usort() makes check against every combination from start to end in order to sort.Now, coming back to array_map(), the reason we are using it is because you have nested arrays.
What the array_map() actually does is, passes all your @days to the usort. And then the usort takes all your @class and sorts accordingly. If you see the following demo, where your @weeks have been taken out only @days and @class present, the above code will not work and will throw you errors of 'Start Time' not being found because you are trying to traverse through 2 nested arrays when only 1 is present:
Demo
For the above structure, the right method will be to implement usort directly without using array_map like:
Demo
Sort nested array using another array with PHP
You can flip the first array in order to know what's the order of the id's:
$order = array_flip($order);
Then you simply use usort to sort the array based on the earlier flipped array:usort($array, static function(array $a, array $b) use ($order) {
return $order[$a['nr']] <=> $order[$b['nr']];
});
Sort and array in PHP by MULTIPLE nested values?
What you're looking for is the function usort()
.
There, you can supply your own comparator that can compare two elements and apply the rules you wish to use.
You were on the right track, but your comparator function can be much more elaborate:
function compare_elements($l, $r) {
if ($l['wins'] > $r['wins']) {
return -1;
} else if ($l['wins'] < $r['wins']) {
return 1;
}
// Drop to second level; it will have exited by here
// if the tie could be broken by the first rule.
// You really could've put this in an else clause, but I
// wanted to avoid excessive nesting.
if ($l['loss'] > $r['loss']) {
return 1;
} else if ($l['loss'] < $r['loss']) {
return -1;
}
// And so on until the 4th level
}
Sort multidimensional array by column value within a column
Try this...
<?php
$array = [
[
'project_id' => 1,
'earnest_money_due' => [
'value' => 1000.00,
'currency' => 'USD',
],
],
[
'project_id' => 2,
'earnest_money_due' => [
'value' => 200.00,
'currency' => 'USD',
],
],
[
'project_id' => 3,
'earnest_money_due' => [
'value' => 900.00,
'currency' => 'USD',
],
],
];
array_multisort(
array_map(
static function ($element) {
return $element['earnest_money_due']['value'];
},
$array
),
SORT_ASC,
$array
);
var_dump($array);
Related Topics
Replace Any Url's Within a String of Text, to Clickable Links with PHP
Upload File Using Guzzle 6 to API Endpoint
How to Build a Condition Based Query in Laravel
What Is the Correct Format for a Blowfish Salt Using PHP's Crypt
Typecasting VS Function to Convert Variable Type in PHP
PHP MySQL - Insert into Without Using Column Names But with Autoincrement Field
Change Xml Node Element Value in PHP and Save File
Get First Element in PHP Stdobject
Get Query Back from Pdo Prepared Statement
Phpexcel Get Formatted Date as Is Visible in Excel File
How to Convert Ldap Timestamp to Unix Timestamp
Regex to Conditionally Replace Twitter Hashtags with Hyperlinks
Save CSV Files into MySQL Database
Codeigniter 3 - Access Session from Outside Codeigniter Installation