MultiDev
MultiDev

Reputation: 10649

PHP: Sort array by value length

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?

Upvotes: 5

Views: 10234

Answers (5)

Luis Masuelli
Luis Masuelli

Reputation: 12333

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

Upvotes: 1

Zombo
Zombo

Reputation: 1

Another method:

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

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

Upvotes: 0

AbraCadaver
AbraCadaver

Reputation: 78994

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

Upvotes: 19

jcbwlkr
jcbwlkr

Reputation: 7999

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

Upvotes: 4

denisvm
denisvm

Reputation: 730

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

Upvotes: 1

Related Questions