Comum
Comum

Reputation: 453

Sort() returns an out of order array

I have an array that is populated from the function iterator_to_array. After I sort it (tried asort(), ksort() and rsort() and all of them show the same result: an out of order array...

This is my code.

$fi = new FilesystemIterator($location, FilesystemIterator::SKIP_DOTS);
$file_paths = iterator_to_array( $fi, false);
rsort($file_paths);
echo "<pre>", print_r($file_paths), "</pre>";

The print_r returns:

Array
(
[0] => SplFileInfo Object
    (
        [pathName:SplFileInfo:private] => /opt/lampp/htdocs/majo/log_files/teste/log2014324.txt
        [fileName:SplFileInfo:private] => log2014324.txt
    )

[1] => SplFileInfo Object
    (
        [pathName:SplFileInfo:private] => /opt/lampp/htdocs/majo/log_files/teste/log2014325.txt
        [fileName:SplFileInfo:private] => log2014325.txt
    )

[2] => SplFileInfo Object
    (
        [pathName:SplFileInfo:private] => /opt/lampp/htdocs/majo/log_files/teste/log2014323.txt
        [fileName:SplFileInfo:private] => log2014323.txt
    )

[3] => SplFileInfo Object
    (
        [pathName:SplFileInfo:private] => /opt/lampp/htdocs/majo/log_files/teste/log2014322.txt
        [fileName:SplFileInfo:private] => log2014322.txt
    )

)

After a routine to clear the name of the file I get this output:

2014324.txt
2014325.txt
2014323.txt
2014322.txt

However because of rsort() (the function used at that time) it should be:

2014325.txt
2014324.txt
2014323.txt
2014322.txt

Everytime the 2014325.txt is out of place and I can't seem to get it in place, does anyone know how to fix this?

I can implement a solution that involves doing the sorting in a manual way, but it will spend a lot more time and resources, however.

PS: ksort() output:

2014322.txt
2014323.txt
2014325.txt
2014324.txt

Upvotes: 0

Views: 283

Answers (3)

georg
georg

Reputation: 214959

iterator_to_array gives you an array of objects, but php has no clue how to compare them. You have to extract the sort key (e.g. a path) and tell php to sort by this key, for example:

$fi = new FilesystemIterator($location, FilesystemIterator::SKIP_DOTS);
$file_paths = array();
foreach($fi as $f)
    $file_paths[$f->getRealPath()] = $f;
ksort($file_paths);

If you only need file paths and not interested in additional data SplFileInfo provides, then glob might be a simpler option:

$file_paths = glob("$location/*");

Note that the glob output is already sorted.

Upvotes: 2

Serpes
Serpes

Reputation: 672

Use usort function:

function my_sort_function($a,$b){
   if ($a->{fileName:SplFileInfo:private} == $b->{fileName:SplFileInfo:private}){
      return 0;
   }
   return ($a->{fileName:SplFileInfo:private} > $b->{fileName:SplFileInfo:private})?1:-1;
}
$fi = new FilesystemIterator($location, FilesystemIterator::SKIP_DOTS);
$file_paths = iterator_to_array( $fi, false);
usort($file_paths,'my_sort_function');
echo "<pre>", print_r($file_paths), "</pre>";

I'm not sure how to access the property of you model but I hope this works

Upvotes: 1

RichardBernards
RichardBernards

Reputation: 3097

You are sorting the first level of the array (the objects without content). The second level of the array (so to speak... actually the contents of the object) contain the values you want to sort.

You will need to create a different method which sorts it correctly for you.

Upvotes: 2

Related Questions