Search code examples
phparraysasortinstruction-reordering

Sort array values by specific order given in another array


I have this array that is the correct order:

$orderDoc = array("ORT", "TRI", "CONT", "RMI");

These documents are in different tables of several servers and database.
At the end of doing the search of the documents I usually get an array with the following structure but with the elements in disarray:

//simulated variable:

$FindDoc= array("RMI0000191","ORT0000379","ORT0000391","ORT0000392","ORT0000390","CONT0000274","CONT0000275","RMI0000192","ORT0000391");

Ouput:

array(10) {
  [0]=>
  string(10) "RMI0000191"
  [1]=>
  string(10) "ORT0000379"
  [2]=>
  string(10) "ORT0000391"
  [3]=>
  string(10) "ORT0000392"
  [4]=>
  string(10) "ORT0000390"
  [5]=>
  string(11) "CONT0000274"
  [6]=>
  string(11) "CONT0000275"
  [7]=>
  string(10) "RMI0000192"
  [8]=>
  string(10) "ORT0000394"
  [9]=>
  string(10) "TRI0000170"
}

I try to use this but it doesn't work. I get an error because the second parameter need to be integer:

$FindDoc=asort($FindDoc,$orderDoc );

After investigate none of this native function work:

PHP - Sort Functions For Arrays
In this chapter, we will go through the following PHP array sort functions:

sort() - sort arrays in ascending order
rsort() - sort arrays in descending order
asort() - sort associative arrays in ascending order, according to the value
ksort() - sort associative arrays in ascending order, according to the key
arsort() - sort associative arrays in descending order, according to the value
krsort() - sort associative arrays in descending order, according to the key

https://www.w3schools.com/php/php_arrays_sort.asp

How can I get the proper order of values?

Example of what was expected, order by $orderDoc ordes and By numeric Document:

array(10) {
  [0]=>
  string(10) "ORT0000379"
  [1]=>
  string(10) "ORT0000390"
  [2]=>
  string(10) "ORT0000391"
  [3]=>
  string(10) "ORT0000392"
  [4]=>
  string(10) "ORT0000394"
  [5]=>
  string(10) "TRI0000170"
  [6]=>
  string(11) "CONT0000274"
  [7]=>
  string(11) "CONT0000275"
  [8]=>
  string(10) "RMI0000191"
  [9]=>
  string(10) "RMI0000192"
}

Update I try to use a custom function but get the somes error's:

foreach ($FindDoc as $StructureMember) {
    $key = array_search($StructureMember, function ($StructureMember, $orderDoc ) {
        return (strpos($StructureMember, $orderDoc ));
    });
    $result[$key] = $StructureMember;
}
$FindDoc = $result;

output:

Warning: array_search() expects parameter 2 to be array, object given in C:\xampp\htdocs\class\class.docinfo.php on line 15

Solution

  • Loop the orderdoc and use preg_grep to get all array items that start with the same characters.
    Then sort the array that is returned and merge them in to the result array.

    $orderDoc = array("ORT", "TRI", "CONT", "RMI");
    
    $FindDoc= array("RMI0000191","ORT0000379","ORT0000391","ORT0000392","ORT0000390","CONT0000274","CONT0000275","RMI0000192","ORT0000391");
    
    $result =[];
    foreach($orderDoc as $doc){
        $temp = preg_grep("/^". preg_quote($doc) . "/", $FindDoc);
        sort($temp);
        $result = array_merge($result, $temp);
    }
    
    var_dump($result);
    

    $result:

    array(9) {
      [0]=>
      string(10) "ORT0000379"
      [1]=>
      string(10) "ORT0000390"
      [2]=>
      string(10) "ORT0000391"
      [3]=>
      string(10) "ORT0000391"
      [4]=>
      string(10) "ORT0000392"
      [5]=>
      string(11) "CONT0000274"
      [6]=>
      string(11) "CONT0000275"
      [7]=>
      string(10) "RMI0000191"
      [8]=>
      string(10) "RMI0000192"
    }
    

    https://3v4l.org/eqUBv

    Notice: this preserves the duplicates from your array.
    You don't say that they should be removed but if you want them removed just add a array_unique() before temp is merged in the $result