I have an array of range type values 257-1024, 1-256, 1025-2056. All these values are dynamically generated and positioned randomed. Before making an output I have to sort them in a numeric ASC order. Using sort or natsort function is giving the output as 1-256,1025-2056, 257-1024 as php recognise it as string. Is there a built in function with which this can be sorted/arranged in numeric range order i.e 1-256, 257-1024, 1025-2056
You can use natsort() function here.
$array = array("257-1024", "1-256", "1025-2056");
$a = natsort($array);
echo "<pre>";
print_r($array);
echo "</pre>";
Output:
Array
(
[1] => 1-256
[0] => 257-1024
[2] => 1025-2056
)
Hope this helps.
You can do like below using usort().
$array = ['257-1024', '1025-2056', '1-256'];
usort($array, function($a, $b){
return ((int)explode('-', $a)[1] < (int)explode('-', $b)[0]) ? -1 : 1;
});
print_r($array);
Output is below.
Array
(
[0] => 1-256
[1] => 257-1024
[2] => 1025-2056
)
Related
Since this question has a long explanation, I'll ask the question, then have the explanation below -- Can you sort a multidimensional array by their internal array key value, or is there a better way to get around sorting key value pairs that will have inevitable duplicates, than just using an array?
I am mostly unfamiliar with using PHP and want to learn how to store data.
The very simple example I made is just two HTML form inputs for a score and a name and a PHP file to handle the input to be stored in a plain .txt file, which was originally written with the pattern
42|John
32|Jane
25|John
I was able to successfully split the data, sort it, add the new inputted values then store it all back in the text file to be displayed somewhere else, using the name as the key and the score as the value.
I did all this only to realize that it would only store sort and display the last value associated with each name (i.e.)
42|John
32|Jane
25|John
would be sorted to
32|Jane
25|John
because you, obviously, can't have two of the same keys in an array, which is something I completely overlooked.
My solution, currently is to have an extra number that is unique to each name/score pair, which I formatted in the text file as
1|42|John
2|32|Jane
3|25|John
I then split them into a multidimensional array using this foreach loop
foreach($arr as $key => $value) {
$lineData = explode("|", $value);
$scores[$lineData[0]] = array($lineData[1] => $lineData[2]);
}
To get this output
Array
(
[1] => Array
(
[42] => John
)
[2] => Array
(
[32] => Jane
)
[3] => Array
(
[25] => John
)
)
which avoids overwriting any duplicate names or scores, but leaves me in a position where I can't (to my knowledge) use arsort() to sort the array in to highest to lowest.
You can use array_multisort for that, in combination with array_column. Because the key values are strings, you need to also convert them to integers, for which you can use array_map("intval", ...):
foreach($arr as $value) {
$result[] = explode("|", $value);
}
array_multisort(array_map("intval", array_column($result, 0)), $result);
After the above code has run, $result will be sorted by the key values:
[
['25', 'John'],
['32', 'Jane'],
['42', 'John']
]
To reverse the order, apply array_reverse to the result.
Alternative
You could also decide to sort the original array without conversion to a 2D array, and sort it with a custom sort callback, using usort and (again) intval:
usort($arr, function ($a, $b) {
return intval($a) - intval($b);
});
Then $arr will be sorted to:
[
'25|John',
'32|Jane',
'42|John'
]
To reverse the order, switch the position of $a and $b in the sort callback function:
return intval($b) - intval($a);
If we make a small change to your foreach iteration like this:
foreach($arr as $key => $value) {
$lineData = explode("|", $value);
$scores[] = array('score' => $lineData[1], 'name' => $lineData[2]);
}
Your array will have:
Array
(
[0] => Array
(
[score] => 42
[name] => John
)
[1] => Array
(
[score] => 32
[name] => Jane
)
[2] => Array
(
[score] => 25
[name] => John
)
)
You can use the uasort function, which takes the array to sort, and an user-defined function to do the sorting. The code would look like this:
function compare($a, $b)
{
if ($b['score'] == $a['score']) {
if ($a['name'] == $b['name']) {
return 0;
} elseif ($a['name'] < $b['name']) {
return -1;
} else {
return 1;
}
} else {
return ($b['score'] - $a['score']);
}
}
print_r($scores);
uasort($scores, 'compare');
print_r($scores);
Which gives the following result:
Array
(
[1] => Array
(
[score] => 32
[name] => Jane
)
[2] => Array
(
[score] => 25
[name] => John
)
[0] => Array
(
[score] => 42
[name] => John
)
)
When you use a user-defined function for the sorting you need to return one of 3 values (0 of the values as equal, -1 if $a < $b, and 1 if $b > $a. In this case we're sorting first by score (descending), then by name (ascending). Since you need to order from highest to lowest score, the comparison is $b against $a, for ascending order is $a against $b. I didn't consider the extra number necessary. If you need it then change this line:
$scores[] = array('score' => $lineData[1], 'name' => $lineData[2]);
To this:
$scores[$lineData[0]] = array('score' => $lineData[1], 'name' => $lineData[2]);
$array = array('0'=>'5', '1'=>'4', '2'=>'1', '3'=>'2');
Array
(
[0] => 5
[1] => 4
[2] => 1
[3] => 2
)
Expecting result
Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 5
)
$array = array('0'=>'5', '1'=>'4', '2'=>'1', '3'=>'2');
$results = [];
foreach($array as $key=>$value){
$results[$key] = arsort($value);
}
echo "<pre>";
print_r($results);
Please suggest how do we can sort associative array i did try but does not work for me please guide
As per your "expected results' it seems like you don't wish to maintain the keys. If that's the case then you can just use sort.
Something like this..
$array = array('0'=>'5', '1'=>'4', '2'=>'1', '3'=>'2');
sort($array);
print_r($array);
Just do
sort($array);
Also check the PHP documentation if you need further customization: http://php.net/manual/en/function.sort.php
var_dump( array_reverse($array,false));
you don't need to use foreach or sort ,you can just use array_reverseinstead ,avery simple way
You don't need to iterate using foreach for sorting
Just use sort for sorting array
$array = array('0'=>'5', '1'=>'4', '2'=>'1', '3'=>'2');
sort($array);
print_r($array);
This will not maintain array keys and if you want arrays keys to be same just replace sort with asort in above code
In the following array, I want to change the key order from high to low (so for example the year 2014 data appears first).
print_r($array);
Output:
Array
(
[0] => Array
(
[year] => 2013
[name] => xx
)
[1] => Array
(
[year] => 2014
[name] => xx
)
)
I have tried using rsort, but it returns only "1".
$array = rsort($array);
print_r($array); //1
var_dump($array); //bool(true).
rsort() will only work on single-dimensional arrays. You have a 2-dimensional array, so you will need to use a different function such as usort(), which lets you use user-defined comparison function for sorting:
usort($data, function ($a, $b) {
return $a['year'] < $b['year'];
});
Output:
Array
(
[0] => Array
(
[year] => 2014
[name] => xx
)
[1] => Array
(
[year] => 2013
[name] => xx
)
)
Working demo
change
$array = rsort($array);
print_r($array);
to
rsort($array);
print_r($array);
rsort has return value of boolean, so just simple use it like this:
rsort($array);
And also, rsort is sorting array values in reverse order, not array keys, check the documentation:
http://php.net/manual/en/function.rsort.php
So in reverse order simply just use krsort - Sort an array by key in reverse order:
http://php.net/manual/en/function.krsort.php
So your code:
krsort($array);
usort($array, function($item1, $item2){
if ($item1->year > $item2->year ) return true;
else return false;
})
That´s if you wanted to order by year, if you want to order by keys uksort could be used instead
I've taken a look at a few googles and actually found this stack too: How to sort a date array in PHP
I'ts on the same wave length but i'm not sure i get it clearly. I've read over the phpnet documentation too... As I said, i'm feeling shakey from it.
I have an array:
Array
(
[0] => Array
(
[created] => 2012-06-06 21:26:25
)
[1] => Array
(
[created] => 2012-06-06 21:23:45
)
)
And I basically need to sort this array so that they are in date order.
How does this call back function work for usort? Any examples would be great!
function MySort($a, $b)
{
if ($a['created'] == $b['created']) return 0;
return $a['created'] < $b['created'] ? -1 : 1;
}
then use...
usort($myarray, "MySort");
usort just lets you sort using your own criteria. You can just simply do this:
usort($array, function($a, $b){
$a = strtotime($a['created']);
$b = strtotime($b['created']);
return $a-$b;
});
I have the following array:
Array ( [0] => Array
( [name] => Jonah
[age] => 27 )
[1] => Array
( [name] => Bianca
[age] => 32 )
)
Is it possible to sort the sub-array values in [age] into some sort of order, such as lowest to highest or vice versa?
You can do this using usort:
usort($arr, function($a, $b)
{
return $a['age'] - $b['age']; // sorts lowest to highest
});
Swap $a and $b in the function to reverse the ordering.
I think this should be possible with bool usort ( array &$array , callback $cmp_function )
http://php.net/manual/en/function.usort.php
Just define a callback that sorts by the [age] key of the value.
This will work:
$ages = array();
foreach ($array as $value) {
$ages[] = $value;
}
array_multisort($values, SORT_ASC, $array);
Any way is good, but this is the "PHP way":
array_multisort() can be used to sort several arrays at once, or a multi-dimensional array by one or more dimensions.