Reputation: 1334
I have two php arrays. And have a different sorting question for each of these arrays:
1) First contains list of domains:
values[0] = "absd.com";
values[1] = "bfhgj.org";
values[2] = "sdfgh.net";
values[3] = "sdff.com";
values[4] = "jkuyh.ca";
I need to sort this array alphabetically by DOMAIN value, in other words by the value after the '.', so the sorted domain will be as follows:
values[0] = "jkuyh.ca";
values[1] = "absd.com";
values[2] = "sdff.com";
values[3] = "sdfgh.net";
values[4] = "bfhgj.org";
2) I also have second array that contains "double" domain values:
values[0] = "lkjhg.org.au";
values[1] = "bfhgj.co.uk";
values[2] = "sdfgh.org.uk";
I need to sort this array alphabetically by DOUBLE DOMAIN value, in other words by the value after the first instance of '.' in domain, so the sorted domain will be as follows:
values[1] = "bfhgj.co.uk";
values[0] = "lkjhg.org.au";
values[2] = "sdfgh.org.uk";
How do I tackle this issue? sort()
approach sorts only based on first letter...
Upvotes: 3
Views: 3300
Reputation: 47874
It is import to not only sort on the second half of the string, but then also break ties using the first half of the string. Otherwise, sorting will appear to be unfinished.
To ensure a fully considered sort, sort from the first dot to the end, then sort on the full string to use the substring before the first do.
Code: (Demo)
usort(
$array,
fn($a, $b) =>
[strstr($a, '.'), $a]
<=>
[strstr($b, '.'), $b]
);
var_export($array);
Upvotes: 0
Reputation: 8641
Another variant:
usort ($values,
function ($a,$b) {
return strcmp (strstr ($a, '.'), strstr ($b, '.'));
});
this will work for both your arrays, since the comparison uses the part of the string starting at the first '.'
If you want to print them out by groups, I think a good solution would be to first create a suitable data structure and then use it both for sorting and printing:
$values = array ("zercggj.co.uk", "lkjhg.org.au", "qqxze.org.au",
"bfhgj.co.uk", "sdfgh.org.uk");
echo "<br>input:<br>";
foreach ($values as $host) echo "$host<br>";
// create a suitable structure
foreach ($values as $host)
{
$split = explode('.', $host, 2);
$printable[$split[1]][] = $split[0];
}
// sort by domains
asort ($printable);
// output
echo "<br>sorted:<br>";
foreach ($printable as $domain => $hosts)
{
echo "domain: $domain<br>";
// sort hosts within the current domain
asort ($hosts);
// display them
foreach ($hosts as $host)
echo "--- $host<br>";
}
This is a good illustration of how you can benefit from thinking about what you will do with your data as a whole instead on focussing on unconnected sub-tasks (like sorting in that case).
Upvotes: 2
Reputation: 324610
usort
is the answer.
Try this:
usort($values,function($a,$b) {
return strcasecmp(
explode(".",$a,2)[1],
explode(".",$b,2)[1]
);
});
(Note that you will need to store the result of explode
in a temporary variable and access that separately, if you're still using PHP 5.3 or older)
Upvotes: 6