Fluidbyte
Fluidbyte

Reputation: 5210

Sort array by sub-array element value in PHP

I'm using readdir to loop files into an array and getting back this result:

Array
(
  [0] => Array
    (
        [name] => /css
        [type] => directory
        [size] => 0
    )

  [1] => Array
    (
        [name] => /index.html
        [type] => file
        [size] => 1208
    )

  [2] => Array
    (
        [name] => /js
        [type] => directory
        [size] => 0
    )
)

My goal is to get them in typical 'file structure format' whereas it's ordered first by type (directories then files), then by name alphabetically.

Upvotes: 1

Views: 193

Answers (2)

maaudet
maaudet

Reputation: 2358

function custom_order($a, $b)
{
    $type_cmp = -strcmp($b['type'], $a['type']);

    if ($type_cmp == 0)
    {
        return -strcmp($b['file'], $a['file']);
    }
    else
    {
        return $type_cmp;
    }
}

$test = array
(
  0 => array
    (
        'name' => '/css',
        'type' => 'directory',
        'size' => 0
    ),

  1 => array
    (
        'name' => '/index.html',
        'type' => 'file',
        'size' => 1208
    ),

  2 => array
    (
        'name' => '/js',
        'type' => 'directory',
        'size' => 0
    )
);

// http://www.php.net/manual/en/function.usort.php
usort($test, 'custom_order'); 

var_dump($test);

I have made a single-liner for fun. (Not that recommended in the name of code clarity)

function custom_order($a, $b)
{
    return ($type_cmp = -strcmp($b['type'], $a['type'])) === 0 ? -strcmp($b['file'], $a['file']) : $type_cmp;
}

Upvotes: 1

ipoga
ipoga

Reputation: 394

If you want to be sophisticated (which may not be necessary, given the circumstances - I assume you will have relatively few entries (~100) in each array), you should look into divide-and.conquer sorting algorithms for speed optimisation (see e.g. http://www.ics.uci.edu/~eppstein/161/960118.html or look in wikipedia for a general overview).

Sophistication aside, however, you can do like this:

function colSort(&$arr, $col, $dir = SORT_ASC) {
   $sort = array();
   foreach ($arr as $k => $r) {
     $sort[$k] = $r[$col];
   }
   array_multisort($sort, $dir, $arr);
 }

You can then use e.g. colSort($array, 'type'); to sort by type. The example can be further modified to sort by filesize or filename as well.

Upvotes: 0

Related Questions