This question already has an answer here:
- How can I sort arrays and data in PHP? 9 answers
I have CSV data loaded into a multidimensional array. In this way each "row" is a record and each "column" contains the same type of data. I am using the function below to load my CSV file.
function f_parse_csv($file, $longest, $delimiter)
{
$mdarray = array();
$file = fopen($file, "r");
while ($line = fgetcsv($file, $longest, $delimiter))
{
array_push($mdarray, $line);
}
fclose($file);
return $mdarray;
}
I need to be able to specify a column to sort so that it rearranges the rows. One of the columns contains date information in the format of Y-m-d H:i:s
and I would like to be able to sort with the most recent date being the first row.
Here is a php4/php5 class that will sort one or more fields:
Introducing: a very generalized solution for PHP 5.3+
I 'd like to add my own solution here, since it offers features that other answers do not.
Specifically, advantages of this solution include:
DateTime
instance).usort
oruasort
).array_multisort
: whilearray_multisort
is convenient, it depends on creating a projection of all your input data before sorting. This consumes time and memory and may be simply prohibitive if your data set is large.The code
How to use
Throughout this section I will provide links that sort this sample data set:
The basics
The function
make_comparer
accepts a variable number of arguments that define the desired sort and returns a function that you are supposed to use as the argument tousort
oruasort
.The simplest use case is to pass in the key that you 'd like to use to compare data items. For example, to sort
$data
by thename
item you would doSee it in action.
The key can also be a number if the items are numerically indexed arrays. For the example in the question, this would be
See it in action.
Multiple sort columns
You can specify multiple sort columns by passing additional parameters to
make_comparer
. For example, to sort by "number" and then by the zero-indexed column:See it in action.
Advanced features
More advanced features are available if you specify a sort column as an array instead of a simple string. This array should be numerically indexed, and must contain these items:
Let's see how we can use these features.
Reverse sort
To sort by name descending:
See it in action.
To sort by number descending and then by name descending:
See it in action.
Custom projections
In some scenarios you may need to sort by a column whose values do not lend well to sorting. The "birthday" column in the sample data set fits this description: it does not make sense to compare birthdays as strings (because e.g. "01/01/1980" comes before "10/10/1970"). In this case we want to specify how to project the actual data to a form that can be compared directly with the desired semantics.
Projections can be specified as any type of callable: as strings, arrays, or anonymous functions. A projection is assumed to accept one argument and return its projected form.
It should be noted that while projections are similar to the custom comparison functions used with
usort
and family, they are simpler (you only need to convert one value to another) and take advantage of all the functionality already baked intomake_comparer
.Let's sort the example data set without a projection and see what happens:
See it in action.
That was not the desired outcome. But we can use
date_create
as a projection:See it in action.
This is the correct order that we wanted.
There are many more things that projections can achieve. For example, a quick way to get a case-insensitive sort is to use
strtolower
as a projection.That said, I should also mention that it's better to not use projections if your data set is large: in that case it would be much faster to project all your data manually up front and then sort without using a projection, although doing so will trade increased memory usage for faster sort speed.
Finally, here is an example that uses all the features: it first sorts by number descending, then by birthday ascending:
See it in action.
I prefer to use array_multisort. See the documentation here.
Before I could get the TableSorter class to run I had came up with a function based on what Shinhan had provided.
I tried several popular array_multisort() and usort() answers and none of them worked for me. The data just gets jumbled and the code is unreadable. Here's a quick a dirty solution. WARNING: Only use this if you're sure a rogue delimiter won't come back to haunt you later!
Let's say each row in your multi array looks like: name, stuff1, stuff2:
Need your stuff back in alphabetical order?
Yeah, it's dirty. But super easy, won't make your head explode.
http://qaify.com/sort-an-array-of-associative-arrays-by-value-of-given-key-in-php/