Acidon
Acidon

Reputation: 1334

How to alphabetically sort a php array after a certain character in a string

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

Answers (3)

mickmackusa
mickmackusa

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

kuroi neko
kuroi neko

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

Niet the Dark Absol
Niet the Dark Absol

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

Related Questions