5

I am trying to sort an array by the length of characters in each value (and perhaps, if possible, in alphabetical order if two values have the same length of characters). For example:

Array ( [0] => this [1] => is [2] => a [3] => bunch [4] => of [5] => words;

I am trying to sort this array to look like:

Array ( [0] => a [1] => is [2] => of [3] => this [4] => bunch [5] => words;

How?

5 Answers 5

19

This should do it:

array_multisort(array_map('strlen', $array), $array);
  • Get the length of each string in an array by mapping strlen() using array_map()
  • Sort on the string lengths and sort the original array by the string length sorted array using array_multisort()
Sign up to request clarification or add additional context in comments.

Comments

4

Looks like others have already answered but I started writing this so I'm going to post it, dang it! :)

You could take a look at usort

$data = ["this", "is", "a", "bunch", "of", "words"];

usort($data, function($a, $b) {
    $difference =  strlen($a) - strlen($b);

    return $difference ?: strcmp($a, $b);
});

I'm using the Elvis operator ?: to just return the difference based on the string lengths if it's not 0. If it is 0, just return the return value of strcmp

1 Comment

you get +1 since I learned what's the Elvis operator in PHP :p.
1

You can use a custom sort function for this.

function mycmp($a, $b) {
    $cmp = strlen($a) - strlen($b);
    if ($cmp === 0)
        $cmp = strcmp($a, $b);
    return $cmp;
}

usort($array, 'mycmp');

Comments

1

See this:

$myarray = explode(" ", "this is a bunch of words");
usort($myarray, function($a, $b) { return strlen($a) - strlen($b) });
print_r($array);

Explanation: usort sorts in place (i.e. by reference) an array, given a custom comparator. A comparator must return a negative number if the first item should be before the second item, and a positive otherwise. A value of 0 means they are equal regarding the order.

You can add custom criteria, not related to strlen() when the lengths are the same. That's up to you and involves just an additional if block.

It is important to note that the function must define an order relationship, as in math:

  1. criteria(a, b)>0 and criteria(b, c)>0 implies criteria(a, c)>0.
  2. the same applies to the lower-than sign, lower-than-or-equal, greater-than-or-equal, and equal.
  3. criteria(a, b) should have an opposite sign of criteria(b, a).

Comments

0

Another method:

$f = fn($s1, $s2) => strlen($s1) <=> strlen($s2);
usort($a, $f);

https://php.net/language.operators.comparison

1 Comment

Calling strlen() twice per iteration of a non-linear function like usort() will not be the efficient way. Follow the top answer's advice to calculate the lengths separately from the sorting action.

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.