1

I need to sort an array. Both values and keys are the same and are strings. Basically, array looks similar to this:

 $test = array(
      '1' => '1',
      '2' => '2',
      '1.5' => '1.5',
      '3' => '3',
      '4' => '4',
      '3.5' => '3.5',
      '2XS' => '2XS',
      '2XL' => '2XL',
      'XXL' => 'XXL',
    );

Expected Output:

 Array
 (
     [0] => 1
     [1] => 1.5
     [2] => 2
     [5] => 3
     [6] => 3.5
     [7] => 4
     [3] => 2XL
     [4] => 2XS
     [8] => XXL
 )

Any ideas?

2
  • 1
    any tries ?? we don't need to re-invent the wheel Commented Apr 12, 2017 at 11:57
  • I tried natural sorting with sort() basically so that won't be of much help. I'm a complete noob at this. Commented Apr 12, 2017 at 12:07

4 Answers 4

4

PHP code demo

<?php 
$test = array(
      '1' => '1',
      '2' => '2',
      '1.5' => '1.5',
      '3' => '3',
      '4' => '4',
      '3.5' => '3.5',
      '2XS' => '2XS',
      '2XL' => '2XL',
      'XXL' => 'XXL',
    );
$numericArray=array();
$stringsArray=array();
array_map(function($value) use (&$numericArray,&$stringsArray) {
        if(is_numeric($value))
        {
            $numericArray[]=$value;//Here we are putting numeric values
        }
        else
        {
            $stringsArray[]=$value;//Here we are putting string values
        }

}, $test);
sort($numericArray,SORT_NUMERIC);//sorting on numeric basis
sort($stringsArray,SORT_REGULAR);//sorting on string basis
$result=array_merge($numericArray,$stringsArray);//merging both of them
print_r($result);

Output:

Array
(
    [0] => 1
    [1] => 1.5
    [2] => 2
    [3] => 3
    [4] => 3.5
    [5] => 4
    [6] => 2XL
    [7] => 2XS
    [8] => XXL
)
Sign up to request clarification or add additional context in comments.

3 Comments

Why not just foreach? array_map make this way more complicated then it needed.
@nerdlyist Yes it is correct that i could use foreach but usually i use array_map. The above result can be achieved from different methods. but i followed this and thats not an issue.
@nerdlyist It can be a case if anyone is not familier with array_map than after seeing this that person will learn a new function :)
1

The solution using usort, is_numeric and strcmp functions:

usort($test, function ($a, $b) {
    if (is_numeric($a) && is_numeric($b)) {
        return $a - $b;
    } else if (is_numeric($a) && !is_numeric($b)) {
        return -1;
    } else if (!is_numeric($a) && is_numeric($b)) {
        return 1;
    } else {
        return strcmp($a, $b);
    }
});

print_r($test);

The output:

Array
(
    [0] => 1
    [1] => 1.5
    [2] => 2
    [3] => 3
    [4] => 3.5
    [5] => 4
    [6] => 2XL
    [7] => 2XS
    [8] => XXL
)

Comments

1
<?php
$test = array(
    '1' => '1',
    '2' => '2',
    '1.5' => '1.5',
    '3' => '3',
    '4' => '4',
    '3.5' => '3.5',
    '2XS' => '2XS',
    '2XL' => '2XL',
    'XXL' => 'XXL',
);

function sortNandS($array){
    $nums = [];
    $strings = [];

    foreach($array as $elm) {
        is_numeric($elm) ? $nums[]= $elm : $strings[]=$elm;
    }
    sort($nums,SORT_NUMERIC);
    sort($strings,SORT_REGULAR);
    $result=array_merge($nums,$strings);

    return $result;
}

print_r(sortNandS($test));

1 Comment

There is absolutely nothing wrong with @SahilGulati solution and this is very similar just with a function and foreach
0

More efficiently than any previously posted answer, use array_multisort(). By passing an array of is_numeric() return values as the first parameter, your script will enjoy a lower time complexity because the is_numeric() calls will be n. Comparatively, usort() will be calling is_numeric() 2 * n log n (which is less efficient).

Code: (Demo)

array_multisort(
    array_map('is_numeric', $test),
    SORT_DESC,
    $test
);

If you want to see what the usort() equivalent looks like: (Demo)

usort(
    $test,
    fn($a, $b) => [is_numeric($b), $a] <=> [is_numeric($a), $b]
);

Unlike uasort() and array_multisort(), usort() will re-index the array after modifying it.

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.