Create array dynamically in Foreach loop - php

I am trying create an array in a foreach loop, and then sort it by a key.
The for each loop creating the array looks like this:
public function index(){
$query=$this->My_model->get_data();
foreach ($query as $row)
{
$data=array(
Array('Points'=>$points,'Name'=>$row['Name'], 'Phone'=>$row['phone']),
);
function cmp ($a, $b) {
return $a['Points'] < $b['Points'] ? 1 : -1;
}
usort($data, "cmp");
print_r($data);
}
}
But this only returns the first the first item in the array.
However when I input some array items directly such as the below, it works fine and sorts all the array items.
public function index(){
$query=$this->My_model->get_data();
foreach ($query as $row)
{
$data = array (
Array ( 'Points' => 500, 'Name' => 'James Lion' ) ,
Array ( 'Points' => 1200, 'Name' => 'John Smith' ),
Array ( 'Points' => 700, 'Name' => 'Jason Smithsonian' ) );
function cmp ($a, $b) {
return $a['Points'] < $b['Points'] ? 1 : -1;
}
usort($data, "cmp");
print_r($data);
}
}
How do I fix this so that the code in the first snippet, so that works as it does in the second snippet?

You have to change the code piece like this
$data[]=array('Points'=>$points,'Name'=>$row['Name'], 'Phone'=>$row['phone']));
The problem with your code is , you are not creating a multidimensional array and instead overwriting the $row values in $data which eventually has the last data since all the other data is overwritten
Also move your function cmp outside of the foreach loop

Have you tried using your custom sort on the outside, (after building your array on the loop). Consider this example:
public function index()
{
$query = $this->My_model->get_data();
foreach ($query as $row) {
$data[] = array('Points' => $points,' Name' => $row['Name'], 'Phone' => $row['phone']),);
}
function cmp ($a, $b) {
return $a['Points'] < $b['Points'] ? 1 : -1;
}
usort($data, "cmp");
print_r($data);
}

Store your values into array format
lock like this $data[]
foreach ($query as $row)
{
$data[]=array(
Array('Points'=>$points,'Name'=>$row['Name'], 'Phone'=>$row['phone']),
);
}
Then you print the data outside of foreach loop
print_r($data);

Related

PHP object to array sorting by associative key

Good morning, I'm just shook about it but, php has more than 10 ways to sort an array but I can't find one to sort by desired key dynamically.
I cannot set something like some uksorts because it will be filled dynamically. I'm using smarty on the front (which does not have array sort functions) and I'm trying to make a callable static to resort and print sorted arrays on one specific point.
I've applied some logic on it and I think it would be something like this.
Smarty:
{assign var='key' value='category_id'}
{assign var='direction' value='normal'}
{assign var='sortedItem' value=''}
{foreach $object.prop item="item"}
{sortedItem = Class::arraySortBy($item, $key, $direction)}
<a href="{$item['link']}">
{$item['name']}
</a>
{foreach}
PHP:
public static function arraySortBy($elemGroup, $sortBy, $direction) {
if(is_object($elemGroup)){
$elemGroup = (array) $elemGroup;
}
if ($direction == 'normal') {
// here is where i want to sort the elemGroup array by the key i want, as the key is product_id and i want to sort by category_id
} else if ($direction == 'reverse'){
// here the same but in reverse order
} else {
error_log('Direction not properly set.');
}
return $elemGroup;
}
the fact is that i want to re-order the objects bu category_id, and second by product_id IE:
itemA{product_id=1, category_id=1}
itemB{product_id=2, category_id=2}
itemC{product_id=3, category_id=1}
itemE{product_id=4, category_id=1}
itemD{product_id=5, category_id=2}
Result:
itemA
itemB
itemC
itemE
itemD
expected result
itemA
itemC
itemE
itemB
itemD
Is there a way to make this with PHP sorting functions or it has to be custom?
Thanks
Why can't you use uasort?
function custom_array_sort($arr, $sorts)
{
// Either pass an array of sorts, or every argument after the first one.
$sorts = is_array($sorts) ? $sorts : array_slice(func_get_args(), 1);
uasort($arr, function ($a, $b) use (&$arr, $sorts) {
for ($i = 0; $i < count($sorts); $i++) {
if ($a[$sorts[$i]] == $b[$sorts[$i]]) {
if (isset($sorts[$i + 1])) {
$arr = custom_array_sort($arr, array_slice($sorts, 1));
} else {
return 0;
}
} else {
return $a[$sorts[$i]] - $b[$sorts[$i]];
}
}
});
return $arr;
}
Live demo
This works by first comparing the category_id fields.
If these are the same then we compare the product_id. The subtraction is used so that the smaller of the product_ids is sorted before the bigger one.
If the category_ids are not the same then we do the same operation on the category_ids as we did above for product_id.
To implement this into your view, follow this documentation
$smarty->register_function('custom_array_sort', 'custom_array_sort_wrapper');
function custom_array_sort_wrapper($params, &$smarty)
{
if (empty($params['arr'])) {
$arr = [];
} else {
$arr = $params['arr'];
}
if (empty($params['sorts'])) {
$sorts = [];
} else {
$sorts = $params['sorts'];
}
return custom_array_sort($arr, $sorts);
}
This can then be used in your views in the following way:
{custom_array_sort arr=$object sorts=['category_id', 'product_id']}
The advantage of this new implementation is that you can specify as many columns to sort as you like.
It also means that you can specify different columns to sort for different arrays.
If you want to sort by more columns then just add another column name to the $sorts array.
You can you try this function.
function array_sort($array, $on, $order=SORT_ASC){
$new_array = array();
$sortable_array = array();
if (count($array) > 0) {
foreach ($array as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) {
if ($k2 == $on) {
$sortable_array[$k] = $v2;
}
}
} else {
$sortable_array[$k] = $v;
}
}
switch ($order) {
case SORT_ASC:
asort($sortable_array);
break;
case SORT_DESC:
arsort($sortable_array);
break;
}
foreach ($sortable_array as $k => $v) {
$new_array[$k] = $array[$k];
}
}
return $new_array;
}
Example:
Array Value:-
$item_array = array (
'itemA' => array('product_id'=>1, 'category_id'=>1),
'itemB' => array('product_id'=>2, 'category_id'=>2),
'itemC' => array('product_id'=>3, 'category_id'=>1),
'itemD' => array('product_id'=>4, 'category_id'=>1),
'itemE' => array('product_id'=>5, 'category_id'=>2)
);
Use function:-
$itme_list = array_sort($item_array, 'category_id', SORT_ASC);
print_r($itme_list);
Output:
Array
(
[itemA] => Array
(
[product_id] => 1
[category_id] => 1
)
[itemC] => Array
(
[product_id] => 3
[category_id] => 1
)
[itemD] => Array
(
[product_id] => 4
[category_id] => 1
)
[itemB] => Array
(
[product_id] => 2
[category_id] => 2
)
[itemE] => Array
(
[product_id] => 5
[category_id] => 2
)
)
Note: Reference link :-
Sort PHP multi-dimensional array based on key?
How to sort multidimensional array by multiply keys?

Loop over one array as if it was a multidimensional array

I have an array like:
$array = array(
'name' => 'Humphrey',
'email' => 'humphrey#wilkins.com
);
This is retrieved through a function that gets from the database. If there is more than one result retrieved, it looks like:
$array = array(
[0] => array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
[1] => array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
If the second is returned, I can do a simple foreach($array as $key => $person), but if there is only one result returned (the first example), I can't run a foreach on this as I need to access like: $person['name'] within the foreach loop.
Is there any way to make the one result believe its a multidimensional array?
Try this :
if(!is_array($array[0])) {
$new_array[] = $array;
$array = $new_array;
}
I would highly recommended making your data's structure the same regardless of how many elements are returned. It will help log terms and this will have to be done anywhere that function is called which seems like a waste.
You can check if a key exists and do some logic based on that condition.
if(array_key_exists("name", $array){
//There is one result
$array['name']; //...
} else {
//More then one
foreach($array as $k => $v){
//Do logic
}
}
You will have the keys in the first instance in the second yours keys would be the index.
Based on this, try:
function isAssoc(array $arr)
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
if(isAssoc($array)){
$array[] = $array;
}
First check if the array key 'name' exists in the given array.
If it does, then it isn't a multi-dimensional array.
Here's how you can make it multi-dimensional:
if(array_key_exists("name",$array))
{
$array = array($array);
}
Now you can loop through the array assuming it's a multidimensional array.
foreach($array as $key => $person)
{
$name = $person['name'];
echo $name;
}
The reason of this is probably because you use either fetch() or fetchAll() on your db. Anyway there are solutions that uses some tricks like:
$arr = !is_array($arr[0]) ? $arr : $arr[0];
or
is_array($arr[0]) && ($arr = $arr[0]);
but there is other option with array_walk_recursive()
$array = array(
array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
$array2 = array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
);
$print = function ($item, $key) {
echo $key . $item .'<br>';
};
array_walk_recursive($array, $print);
array_walk_recursive($array2, $print);

How to sort all levels of multidimensional array by key?

I found this code for sorting:
usort($array, function($a, $b) {
return $a['order_inside_level'] - $b['order_inside_level'];
});
It's good for one level. I have something like that:
array(
array(
'level'=>'aaa',
'order'='1',
'subs'=>array(
array(
'level'=>'bbb',
'order'='1',
'subs'=>array(
array(
'level'=>'ccc',
'order'='1',
'subs'=>array(
array(
'level'=>'ddd',
'order'='1',
'subs'=>array(
...
)
)
)
)
,
array(
'level'=>'ccc',
'order'='2',
'subs'=>array(
)
)
),
array(
'level'=>'bbb',
'order'='2'
),
array(
'level'=>'bbb',
'order'='3'
)
)
)
),
array(
'level'=>'aaa',
'order'='2',
'subs'=>array(
)
)
)
Array may have any depth and any number of elements in each level. I need to sort each level of depth (aaa,bbb,ccc, etc) using the code above by key 'order'.
You will need to do this recursively.
recursive_sort($arr, $func) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
recursive_sort($val, $func);
}
}
usort($arr, $func);
}
This code will iterate over the given array, and for each value that is an array, call itself with the value. The result is that usort will be called for every array within the structure.
You would call the function the same as you would usort:
recursive_sort($array, function($a, $b) {
return $a['order_inside_level'] - $b['order_inside_level'];
});
function recursive_sort(&$arr) {
fs($arr);
foreach($arr as $k=> &$v){
if (isset($v['subs'])) {
recursive_sort($v['subs']);
}
}
}
function sortByOrder($a, $b) {
return $a['order_inside_level'] - $b['order_inside_level'];
}
function fs(&$array){
usort($array, 'sortByOrder');
}
After multiple tries I have this. It works. Name of key (subs) is hardcoded what is not so good, but... I am glad it works.

Accessing a PHP array

I'm sure this has been asked before, but I can't seem to find the answer.
To that end, I have an array that looks like this:
Array
(
[0] => Array
(
[status] => active
[sid] => 1
)
[1] => Array
(
[status] => expired
[sid] => 2
)
)
What I'd like to be able to do is type $arrayName["active"] and it return the SID code. I will be using this like a dictionary object of sorts. It's like I need to reindex the array so that it is the key/value pair that I need. I was just wondering if there was an easier way to do it.
You should convert your nested arrays into a single associative array. Something like this should take your example and turn it into an associative array:
$assoc_array = array();
foreach( $example_array as $values ) {
$assoc_array[$values["status"]] = $values["sid"];
}
You can then access the sid for a given status by using $assoc_array["expired"] (returns 2)
After seeing the others' solutions, I realize this might be bit of an overkill, but I'm still just gonna throw it out there:
$foo = array(
array('status' => 'active', 'sid' => 1),
array('status' => 'expired', 'sid' => 2),
);
// Get all the 'status' elements of each subarray
$keys = array_map(function($element) {
return $element['status'];
}, $foo);
// Get all the 'sid' elements of each subarray
$values = array_map(function($element) {
return $element['sid'];
}, $foo);
// Combine them into a single array, with keys from one and values from another
$bar = array_combine($keys, $values);
print_r($bar);
Which prints:
Array
(
[active] => 1
[expired] => 2
)
Manual pages:
array_map()
array_keys()
array_values()
array_combine()
Anonymous functions
You can use this function:
function findActive($my_array){
foreach($my_array as $array){
foreach($array as $val){
if($val['status']==='active'){
return $val['sid'];
}
}
}
return false;
}
access it via a loop or directly.
if($arrayName[0]['status'] == "active") {
echo $arrayName[0]['sid'];
}
If you want to check all the SIDs
foreach($arrayName as $item) {
if($item['status'] == "active") {
echo $item['sid'];
}
}
A more direct approach is just putting the loop in a function and return an array of all active session IDs
$sidArr = array();
foreach($yourArr as $val) {
if("active" == $val["status"]) {
array_push($sidArr, $val["sid"]);
}
}
reindex would be the best
$arrayName = array()
foreach ($data_array as $data)
$arrayName[$data['status']]=$data['sid'];
Or use a function
function get_sid($status)
{
global $data_array;
foreach ($data_array as $data) {
if ($data['status']==$status)
return $data['sid'];
}
return false;
}

Sort an array of associative arrays by column value

Given this array:
$inventory = array(
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
I would like to sort $inventory's elements by price to get:
$inventory = array(
array("type"=>"pork", "price"=>5.43),
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
);
How can I do this?
You are right, the function you're looking for is array_multisort().
Here's an example taken straight from the manual and adapted to your case:
$price = array();
foreach ($inventory as $key => $row)
{
$price[$key] = $row['price'];
}
array_multisort($price, SORT_DESC, $inventory);
As of PHP 5.5.0 you can use array_column() instead of that foreach:
$price = array_column($inventory, 'price');
array_multisort($price, SORT_DESC, $inventory);
PHP 7+
As of PHP 7, this can be done concisely using usort with an anonymous function that uses the spaceship operator to compare elements.
You can do an ascending sort like this:
usort($inventory, function ($item1, $item2) {
return $item1['price'] <=> $item2['price'];
});
Or a descending sort like this:
usort($inventory, function ($item1, $item2) {
return $item2['price'] <=> $item1['price'];
});
To understand how this works, note that usort takes a user-provided comparison function that must behave as follows (from the docs):
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
And note also that <=>, the spaceship operator,
returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater
which is exactly what usort needs. In fact, almost the entire justification given for adding <=> to the language in https://wiki.php.net/rfc/combined-comparison-operator is that it
makes writing ordering callbacks for use with usort() easier
PHP 5.3+
PHP 5.3 introduced anonymous functions, but doesn't yet have the spaceship operator. We can still use usort to sort our array, but it's a little more verbose and harder to understand:
usort($inventory, function ($item1, $item2) {
if ($item1['price'] == $item2['price']) return 0;
return $item1['price'] < $item2['price'] ? -1 : 1;
});
Note that although it's fairly common for comparators dealing with integer values to just return the difference of the values, like $item2['price'] - $item1['price'], we can't safely do that in this case. This is because the prices are floating point numbers in the question asker's example, but the comparison function we pass to usort has to return integers for usort to work properly:
Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.
This is an important trap to bear in mind when using usort in PHP 5.x! My original version of this answer made this mistake and yet I accrued ten upvotes over thousands of views apparently without anybody noticing the serious bug. The ease with which lackwits like me can screw up comparator functions is precisely the reason that the easier-to-use spaceship operator was added to the language in PHP 7.
While others have correctly suggested the use of array_multisort(), for some reason no answer seems to acknowledge the existence of array_column(), which can greatly simplify the solution. So my suggestion would be:
array_multisort(array_column($inventory, 'price'), SORT_DESC, $inventory);
If you want Case Insensitive Sort on strings, you can use SORT_NATURAL|SORT_FLAG_CASE
array_multisort(array_column($inventory, 'key_name'), SORT_DESC, SORT_NATURAL|SORT_FLAG_CASE, $inventory);
Since your array elements are arrays themselves with string keys, your best bet is to define a custom comparison function. It's pretty quick and easy to do. Try this:
function invenDescSort($item1,$item2)
{
if ($item1['price'] == $item2['price']) return 0;
return ($item1['price'] < $item2['price']) ? 1 : -1;
}
usort($inventory,'invenDescSort');
print_r($inventory);
Produces the following:
Array
(
[0] => Array
(
[type] => pork
[price] => 5.43
)
[1] => Array
(
[type] => fruit
[price] => 3.5
)
[2] => Array
(
[type] => milk
[price] => 2.9
)
)
I ended on this:
function sort_array_of_array(&$array, $subfield)
{
$sortarray = array();
foreach ($array as $key => $row)
{
$sortarray[$key] = $row[$subfield];
}
array_multisort($sortarray, SORT_ASC, $array);
}
Just call the function, passing the array and the name of the field of the second level array.
Like:
sort_array_of_array($inventory, 'price');
You can use usort with anonymous function, e.g.
usort($inventory, function ($a, $b) { return strnatcmp($a['price'], $b['price']); });
From Sort an array of associative arrays by value of given key in php:
by using usort (http://php.net/usort) , we can sort an array in ascending and descending order. just we need to create a function and pass it as parameter in usort. As per below example used greater than for ascending order if we passed less than condition then it's sort in descending order.
Example :
$array = array(
array('price'=>'1000.50','product'=>'test1'),
array('price'=>'8800.50','product'=>'test2'),
array('price'=>'200.0','product'=>'test3')
);
function cmp($a, $b) {
return $a['price'] > $b['price'];
}
usort($array, "cmp");
print_r($array);
Output:
Array
(
[0] => Array
(
[price] => 200.0
[product] => test3
)
[1] => Array
(
[price] => 1000.50
[product] => test1
)
[2] => Array
(
[price] => 8800.50
[product] => test2
)
)
$inventory =
array(array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
function pricesort($a, $b) {
$a = $a['price'];
$b = $b['price'];
if ($a == $b)
return 0;
return ($a > $b) ? -1 : 1;
}
usort($inventory, "pricesort");
// uksort($inventory, "pricesort");
print("first: ".$inventory[0]['type']."\n\n");
// for usort(): prints milk (item with lowest price)
// for uksort(): prints fruit (item with key 0 in the original $inventory)
// foreach prints the same for usort and uksort.
foreach($inventory as $i){
print($i['type'].": ".$i['price']."\n");
}
outputs:
first: pork
pork: 5.43
fruit: 3.5
milk: 2.9
For PHP 7 and later versions.
/**
* A method for sorting associative arrays by a key and a direction.
* Direction can be ASC or DESC.
*
* #param $array
* #param $key
* #param $direction
* #return mixed $array
*/
function sortAssociativeArrayByKey($array, $key, $direction){
switch ($direction){
case "ASC":
usort($array, function ($first, $second) use ($key) {
return $first[$key] <=> $second[$key];
});
break;
case "DESC":
usort($array, function ($first, $second) use ($key) {
return $second[$key] <=> $first[$key];
});
break;
default:
break;
}
return $array;
}
Usage:
$inventory = sortAssociativeArrayByKey($inventory, "price", "ASC");
I use uasort like this
<?php
$users = [
[
'username' => 'joe',
'age' => 11
],
[
'username' => 'rakoto',
'age' => 21
],
[
'username' => 'rabe',
'age' => 17
],
[
'username' => 'fy',
'age' => 19
],
];
uasort($users, function ($item, $compare) {
return $item['username'] >= $compare['username'];
});
var_dump($users);
As of PHP 7.4, you can use arrow function:
usort(
$inventory,
fn(array $a, array $b): int => $b['price'] <=> $a['price']
);
Code (demo):
$inventory = [
['type' => 'fruit', 'price' => 3.50],
['type' => 'milk', 'price' => 2.90],
['type' => 'pork', 'price' => 5.43],
];
usort(
$inventory,
fn(array $a, array $b): int => $b['price'] <=> $a['price']
);
print_r($inventory);
(condensed) Output:
Array
(
[0] => Array ([type] => pork, [price] => 5.43)
[1] => Array ([type] => fruit, [price] => 3.5)
[2] => Array ([type] => milk, [price] => 2.9)
)
Was tested on 100 000 records:
Time in seconds(calculated by funciton microtime).
Only for unique values on sorting key positions.
Solution of function of #Josh Davis:
Spended time: 1.5768740177155
Mine solution:
Spended time: 0.094044923782349
Solution:
function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC)
{
if (empty($data) or empty($sortKey)) return $data;
$ordered = array();
foreach ($data as $key => $value)
$ordered[$value[$sortKey]] = $value;
ksort($ordered, $sort_flags);
return array_values($ordered); *// array_values() added for identical result with multisort*
}
try this:
$prices = array_column($inventory, 'price');
array_multisort($prices, SORT_DESC, $inventory);
print_r($inventory);
This function is re-usable:
function usortarr(&$array, $key, $callback = 'strnatcasecmp') {
uasort($array, function($a, $b) use($key, $callback) {
return call_user_func($callback, $a[$key], $b[$key]);
});
}
It works well on string values by default, but you'll have to sub the callback for a number comparison function if all your values are numbers.
Here is a method that I found long ago and cleaned up a bit. This works great, and can be quickly changed to accept objects as well.
/**
* A method for sorting arrays by a certain key:value.
* SortByKey is the key you wish to sort by
* Direction can be ASC or DESC.
*
* #param $array
* #param $sortByKey
* #param $sortDirection
* #return array
*/
private function sortArray($array, $sortByKey, $sortDirection) {
$sortArray = array();
$tempArray = array();
foreach ( $array as $key => $value ) {
$tempArray[] = strtolower( $value[ $sortByKey ] );
}
if($sortDirection=='ASC'){ asort($tempArray ); }
else{ arsort($tempArray ); }
foreach ( $tempArray as $key => $temp ){
$sortArray[] = $array[ $key ];
}
return $sortArray;
}
to change the method to sort objects simply change the following line:
$tempArray[] = strtolower( $value[ $sortByKey ] );
to
$tempArray[] = strtolower( $value->$sortByKey );
To run the method simply do
sortArray($inventory,'price','ASC');
You might try to define your own comparison function and then use usort.
//Just in one line custom function
function cmp($a, $b)
{
return (float) $a['price'] < (float)$b['price'];
}
#uasort($inventory, "cmp");
print_r($inventory);
//result
Array
(
[2] => Array
(
[type] => pork
[price] => 5.43
)
[0] => Array
(
[type] => fruit
[price] => 3.5
)
[1] => Array
(
[type] => milk
[price] => 2.9
)
)
Many people are searching for a way to do this with Laravel and ending up here. Also, some Laravel questions are getting closed due to duplicates to this question.
Hence, I shared an easy way to perform it with Laravel collect() method.
$inventory = collect($inventory)->sortBy('price')->toArray();
For Descending order
$inventory = collect($inventory)->sortBy('price')->reverse()->toArray();
Or,
$inventory = collect($inventory)->('price')->reverse()->toArray();
Complete Dynamic Function
I jumped here for associative array sorting and found this amazing function on http://php.net/manual/en/function.sort.php. This function is very dynamic that sort in ascending and descending order with specified key.
Simple function to sort an array by a specific key. Maintains index association
<?php
function array_sort($array, $on, $order=SORT_ASC)
{
$new_array = array();
$sortable_array = array();
if (count($array) > 0) {
foreach ($array as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) {
if ($k2 == $on) {
$sortable_array[$k] = $v2;
}
}
} else {
$sortable_array[$k] = $v;
}
}
switch ($order) {
case SORT_ASC:
asort($sortable_array);
break;
case SORT_DESC:
arsort($sortable_array);
break;
}
foreach ($sortable_array as $k => $v) {
$new_array[$k] = $array[$k];
}
}
return $new_array;
}
$people = array(
12345 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
12346 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
12347 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
)
);
print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname
If you need to sort an array of strings with different cases, this will change the sorting array values to lowercase.
$data = [
[
'name' => 'jack',
'eyeColor' => 'green'
],
[
'name' => 'Amy',
'eyeColor' => 'brown'
],
[
'name' => 'Cody',
'eyeColor' => 'blue'
]
];
function toLowerCase($a) { return strtolower($a); }
$sortArray = array_map("toLowerCase",array_column($data, 'name'));
array_multisort($sortArray, SORT_ASC, $data);
This function works 100% on all major versions of PHP and it is tested with PHP5, PHP7, PHP8.
function sort_my_array($array, $order_by, $order)
{
switch ($order) {
case "asc":
usort($array, function ($first, $second) use ($order_by) {
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
return $first[$order_by] <=> $second[$order_by];
} else {
$array_cmp = strcmp($first[$order_by], $second[$order_by]);
return $array_cmp ;
}
});
break;
case "desc":
usort($certificates, function ($first, $second) use ($order_by) {
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
return $first[$order_by] <=> $second[$order_by];
} else {
$array_cmp = strcmp($first[$order_by], $second[$order_by]);
return -$array_cmp ;
}
});
break;
default:
break;
}
return $array;
}
$arr1 = array(
array('id'=>1,'name'=>'aA','cat'=>'cc'),
array('id'=>2,'name'=>'aa','cat'=>'dd'),
array('id'=>3,'name'=>'bb','cat'=>'cc'),
array('id'=>4,'name'=>'bb','cat'=>'dd')
);
$result1 = array_msort($arr1, array('name'=>SORT_DESC);
$result2 = array_msort($arr1, array('cat'=>SORT_ASC);
$result3 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));
function array_msort($array, $cols)
{
$colarr = array();
foreach ($cols as $col => $order) {
$colarr[$col] = array();
foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
}
$eval = 'array_multisort(';
foreach ($cols as $col => $order) {
$eval .= '$colarr[\''.$col.'\'],'.$order.',';
}
$eval = substr($eval,0,-1).');';
eval($eval);
$ret = array();
foreach ($colarr as $col => $arr) {
foreach ($arr as $k => $v) {
$k = substr($k,1);
if (!isset($ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
}
return $ret;
}
try this:
asort($array_to_sort, SORT_NUMERIC);
for reference see this:
http://php.net/manual/en/function.asort.php
see various sort flags here:
http://www.php.net/manual/en/function.sort.php

Categories