0

I have a function which has to handle a response from a SQL query. I have to reformat it into an array, reorder and return the new array. This is how I configure the array I want to sort

foreach($response as $key => $codigocentro ){
    $centro = Centros::find($codigocentro);//another query using Phormium (this works fine)
    $centro[$key]['da']= $centro->da;
    $centrosAsignados[$key]['descrip'] = $centro->descrip;
    $centrosAsignados[$key]['codigo'] =$codigocentro;
    if (condition){
        $centrosAsignados[$key]['orden_cs_cl'] = $centro->descrip;
        $centrosAsignados[$key]['descrip_cabecera'] =$codigocentro;
    }
}

After that I prepare the multiple filter as shown on the manual https://www.php.net/manual/en/function.array-multisort.php (example 3)

$array_da    = array_column($centrosAsignados, 'da');
$array_cabec = array_column($centrosAsignados, 'descrip_cabecera');
$array_cs_cl = array_column($centrosAsignados, 'orden_cs_cl');
$array_descr = array_column($centrosAsignados, 'descrip');

For a final step:

array_multisort($centrosAsignados, 
                    $array_da, SORT_DESC,
                    $array_cabec,
                    $array_cs_cl );

Now, I seem to have trouble ONLY with $array_cabec since the "da" or the "cs_cl" filters works as expected. The output respects those 2 successful conditions in the order I configured them.

I have outputted the results in many ways before and after, and I've closed the circle to my problem in this particular scenario (Output for these dumps in images below)

var_dump($array_cabec ); // to output initial values on this particular array 
array_multisort($centrosAsignados, $array_cabec) 
$array_cabec2 = array_column($centrosAsignados, 'descrip_cabecera');// reassigning values after sorting
var_dump($array_cabec2 ); // to output final values 

I've already checked similar problems like array_multisort not working properly?

Sort an array with special characters in PHP

How to sort an array of UTF-8 strings?

I've removed the entries with possible special characters and tried several encoding solutions like mb_convert_encoding, utf8_encode, utf8_encode+decode, iconv, trim , etc. With no results (at most I lose the special characters, but no difference in sorting)

The closest I got is the following

asort($array_cabec);

Which actually sorted the fields I need, but is not what I wanted.

I want the filters in array_multisort to apply one over another in a specific order. I will show you the actual output (I'm using postman) of what I'm receiving at this moment:

Before the sorting:
Before image

After the sorting:
After image

I'm expecting all the "C.S. ALGETE" to go in first place (C comes before D so DA_NORTE shouldn't go first). I don't know if I'm applying a right filter, if the flags I've tried should go in a different order or if there is another native function in php for achieving what I need.

For environment information I'm using php7 on windows and the DB where data comes from is coming from Informix database. If more information is needed please notice me in the comments. Information is reduced to ease reading, for example in the images where I haven't displayed all the 81 fields. Please make sure it addresses my problem if you think this question is suitable for marking as duplicate.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Mbotet
  • 170
  • 2
  • 17

1 Answers1

0

After way too more research than expected i solved it with using USORT instead of array_multisort which I still think it has bugs when using strings. Which strings? -I still don't know (comment please if you do).

I dont need anymore the headers array. Usort plus annonymus functions with callbacks works perfect. (as it did with the asort) but i didnt figure out it could work with multidimensional.

    usort($centrosAsignados, function ($a, $b){
        $c = $a['da'] - $b['da'];
        $c .= strcmp( $a['descrip_cabecera'], $b['descrip_cabecera']);
        $c .= $b['orden_cs_cl'] - $a['orden_cs_cl'];
        $c .= strcmp( $a['descrip'], $b['descrip']);
        return $c;
    } );

EDIT: You can trade $a with $b to get ascending or descending order for any of the applied filters. For example:

$a['da'] - $b['da'];  =>  $b['da'] - $a['da'];

Collateral credits to sleipnir214 in

https://www.tek-tips.com/viewthread.cfm?qid=690382

and Nsisodia91 from user contribution in php manual (this answer is a bit below)

https://www.php.net/manual/en/function.usort.php

Mbotet
  • 170
  • 2
  • 17
  • Im suspicious about detecting latin characters "on the go" while it starts sorting in UTF8 when it detects its charset is iso-8859-1 starts sorting the other way. If someone can bring light to this it would be interesting – Mbotet Feb 19 '20 at 07:27
  • Why in the world are you doing subtraction, then appending a potentially negative number to the end of that difference, then another potentially number, then another potentially negative number?!? This is not a professional-grade solution. – mickmackusa Aug 10 '21 at 23:15