2

I'm new to php and have been trying to sort a 2d array of strings, with a specific order array. Have been looking at using 'usort' and 'comparison', but cant seem to wrap my head around them when using 2d array and strings.

Need to input array to method and return sorted array, with same format. So for each entry in array it will sort the 2nd level 'file' value dependant on the order of order array. Any suggestions how to accomplish this?

//actual array to be sorted by 'file'
$Array ( 
[0] => Array ( [source] => img/table/icon/toxic.svg [file] => toxic ) 
[1] => Array ( [source] => img/table/icon/health.svg [file] => health ) 
[2] => Array ( [source] => img/table/icon/irritant.svg [file] => irritant   ));

//order array with desired sort order
$order = array("irritant","corrosive","environment" ,"health","toxic","oxidizing","flammable","explosive","gas");

//Desired Output Result
$Array ( 
[0] => Array ( [source] => img/table/icon/irritant.svg [file] => irritant )
[1] => Array ( [source] => img/table/icon/health.svg [file] => health ) 
[2] => Array ( [source] => img/table/icon/toxic.svg [file] => toxic ) );

See so irritant is first and toxic is last :)

Orbitall
  • 611
  • 11
  • 36

2 Answers2

1

This can be accomplished through clever use of PHP's usort function. Your call may look something like this:

$order = array("irritant","corrosive","environment" ,"health","toxic","oxidizing","flammable","explosive","gas");
usort($array, function ($a, $b) use ($order) {
    $aOrder = array_search($a['file'], $order);
    $bOrder = array_search($b['file'], $order);
    if ($aOrder == $bOrder) return 0;
    return ($aOrder > $bOrder) ? 1 : -1;
});
xathien
  • 812
  • 7
  • 10
  • This that much more effcient to use? just tried it and get an empty array when printing result...probs jus me n my understanding tho. – Orbitall Apr 07 '15 at 16:05
  • It would be measurably more efficient on large arrays than doing it in raw PHP, as `usort()` does it both in-place and using C, making it more memory- and time-efficient. – xathien Apr 07 '15 at 16:13
0

The basic method is to iterate through both the array and the order array and reassign the keys into a new array...

<?php
    $a[] = array('source' => 'img/table/icon/toxic.svg','file'=>'toxic');
    $a[] = array('source' => 'img/table/icon/health.svg','file'=>'health');
    $a[] = array('source' => 'img/table/icon/irritant.svg','file'=>'irritant');

    $b = array();

    $order = array("irritant","corrosive","environment","health","toxic","oxidizing","flammable","explosive","gas");

    foreach ($a as $arr) {
        foreach ($order as $key => $o) {
            if ($o == $arr['file']) {
                $b[$key] = $arr;
                break;
            }
        }
    }
    ksort($b);
    print_r(array_values($b)); // or print_r($b); if you dont want sequential keys
?>

output:

Array ( 
[0] => Array ( [source] => img/table/icon/irritant.svg [file] => irritant ) 
[1] => Array ( [source] => img/table/icon/health.svg [file] => health ) 
[2] => Array ( [source] => img/table/icon/toxic.svg [file] => toxic )
)
zgr024
  • 1,175
  • 1
  • 12
  • 26
  • Thanks that works a treat....looks simple, but wudve taken me a while to figure out using arrayflip and ksort. – Orbitall Apr 07 '15 at 15:48
  • you dont even need the `array_flip`... see my last edit. It can be done without that. Also glad I could help. The usort method that xathien suggested will also work, but for a novice to PHP, it doesn't explain anything. – zgr024 Apr 07 '15 at 15:50