3

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...

1
  • This would be easier if each of your values is an array, split on the .; you could then sort based on the elements in the array. e.g. values[0] = array('absd', 'com');. Commented Jan 25, 2014 at 4:03

3 Answers 3

6

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)

Sign up to request clarification or add additional context in comments.

4 Comments

for some reason strings with explode give me a syntaxis error in editor, but it works for the fist array in question, however doesn't work for the second one
I think the explode limit should be set to 1, in order to sort the complete .xx.yy suffixes from the second array.
@kuroineko So you want to explode a string into one part? That makes sense :p
@NiettheDarkAbsol Oops sorry. I was testing the wrong code and tried to find a quick explanation as of why it would not work. Silly me. Your code works fine, but becomes a bit heavy on older PHP versions.
2

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).

1 Comment

ahh, it worked, and no errors in editor too!! Do you know what is the best way to separate parts of array with same domains into separate groups when I print it out, for example with echo("<br />"); after each group?
0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.