Sorting one array by another

Hi There.

I have the below source:

       //settings
      $path = "/home/mydida/public_html/swfpres/pres/";
      
      // Open the folder
      $dir_handle = @opendir($path);

      //get arrays
      $num = 0;
      while ($file1 = readdir($dir_handle)) {
            $filearray[$num] = $file1;
            $datearray[$num] = filemtime($path.$file1);
            $num++;
      }
      
      //sort file array
      //FIND OUT HOW!!!!!
      
      // Loop through the files
      foreach ($filearray as $key => $file) {

            //get rid of rubbish
            if($file == "." || $file == ".." || $file == "index.php" ) { continue; }
            
            
            print "<a href='".$PHP_SELF."?view=".$file."'>";
            if(!@file_get_contents("pres/".$file."/pres.txt")){
                  print $file." - No details detected!";
            }else{
                  $contents = explode("&*|*&",file_get_contents("pres/".$file."/pres.txt"));
                  print $contents[0];
            }
            print "</a>";
            print " Date = ".date('F d, Y', $datearray[$key])."<br />";

      }

      // Close
      closedir($dir_handle);

Basically, you will see that I created the array "datearray" and the array "filearray". I need to be able to sort the array "filearray", using the values provided by "datearray", without changing the "filearray".

EG: datearray contains values - "12 December 2001", "14 December 2003", "26 February 1999". And filearray contains values "hi1.txt","hi2.txt","hi3.txt".
I would want it to sort the array filearray to be sorted descending according to values in datearray (the keys of both arrays tally up) - "hi2.txt","hi1.txt","hi3.txt".

I am sure there is a way to do this, I just cant find the right way looking on the internet.

Thanks for your time!

Giles Williams.
LVL 3
gileze33Asked:
Who is Participating?
 
Brian BushSolutions ArchitectCommented:
How about this:

<?php

$_path = "c:\\";
$_dir_handle = @opendir($_path);

$_i = 0;
while ($_file = readdir($_dir_handle)) {
     $_files[$_i] = array('file' => $_file, 'date' => filemtime($_path . $_file));
     $_i++;
}

function cmp($a, $b) {
     return strcmp(strtoupper($a['file']), strtoupper($b['file']));
}

//sort file array
usort($_files, "cmp");

foreach ($_files as $_key => $_value) {

     //get rid of rubbish
    if ($_value['file'] == "." || $_value['file'] == ".." || $_value['file'] == "index.php") {
        continue;
    }

    echo "<a href='" . $_SERVER['PHP_SELF'] . "?view=" . $_value['file'] . "'>";

    if(!@file_get_contents("pres/" . $_value['file'] . "/pres.txt")) {
        echo $_value['file'] . " - No details detected!";
    } else {
        $_contents = explode("&*|*&", file_get_contents("pres/" . $_value['file'] . "/pres.txt"));
        echo $_contents[0];
    }

    echo "</a> " . date('F d, Y', $_value['date']) . "<br />";
}

// Close
closedir($_dir_handle);

?>

I threw in a strtoupper in the cmp function to make the listing case-insensitive.
--brian
0
 
RoonaanCommented:
Easier would be to have a single array holding (date, file) tuples:

 while ($file1 = readdir($dir_handle)) {
          $filearray[$num] = array('file'=> $file1, 'date' => filemtime($path.$file1));
          $num++;
     }

Then you can use usort, to sort the array:

usort($filearray, 'mysort');
function mysort($item1, $item2) {
  return strcmp($item1['file'], $item2['file']);
}

-r-
0
 
gileze33Author Commented:
Hi There. Thanks for fast response.

If I did this, how would I then get the values for date and file out from array while in my foreach loop?

Thanks.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
RoonaanCommented:
foreach ($filearray as $key => $fileinfo) {
   $file = $fileinfo['file'];
   $date = $fileinfo['date'];

-r-
0
 
gileze33Author Commented:
I did that got this error:
Warning: usort(): Invalid comparison function. in /home/mydida/public_html/swfpres/index.php on line 18

Source Again:

      //settings
      $path = "/home/mydida/public_html/swfpres/pres/";
      
      // Open the folder
      $dir_handle = @opendir($path);

      //get arrays
      $num = 0;
      while ($file1 = readdir($dir_handle)) {
          $filearray[$num] = array('file'=> $file1, 'date' => filemtime($path.$file1));
          $num++;
    }
      
      //sort file array
      usort($filearray, 'mysort');
            function mysort($item1, $item2) {
            return strcmp($item1['file'], $item2['file']);
      }
      
      // Loop through the files
      foreach ($filearray as $key => $fileinfo) {
            
            //set values
            $file = $fileinfo['file'];
               $date = $fileinfo['date'];
            
            //get rid of rubbish
            if($file == "." || $file == ".." || $file == "index.php" ) { continue; }
            
            
            print "<a href='".$PHP_SELF."?view=".$file."'>";
            if(!@file_get_contents("pres/".$file."/pres.txt")){
                  print $file." - No details detected!";
            }else{
                  $contents = explode("&*|*&",file_get_contents("pres/".$file."/pres.txt"));
                  print $contents[0];
            }
            print "</a>";
            print " ".date('F d, Y', $date)."<br />";

      }

      // Close
      closedir($dir_handle);
0
 
Harisha M GCommented:
How about this:

array_multisort($datearray, SORT_DESC, SORT_NUMERIC, $filearray);


Ex:

<?php
      $filearray = array("hi1.txt","hi2.txt", "hi3.txt");
      $datearray = array(strtotime("12 December 2001"), strtotime("14 December 2003"),strtotime( "26 February 1999"));

      var_dump($filearray);
      var_dump($datearray);

      
      array_multisort($datearray, SORT_DESC, SORT_NUMERIC, $filearray);

      var_dump($filearray);
      var_dump($datearray);
?>
0
 
Brian BushSolutions ArchitectCommented:
oh yeah, I made the path="C:\\" so I could test it on my laptop.
--brian
0
 
gileze33Author Commented:
theonlygoodisknowledge

Seems to work, but is it neccessary to have variables as $_variable?, as this mucks up code sent to other pages.

Giles.
0
 
Brian BushSolutions ArchitectCommented:
Nope. It's just a naming convention I use for private variables.
You can name them anything you want.

--brian
0
 
RoonaanCommented:
Hi gileze33, try this function for the mysort. strcmp doesn't work as I though it would.

     //sort file array
     function mysort($item1, $item2) {
          if($item1['file'] == $item2['file']) return 0;
          return strcmp($item1['file'], $item2['file']) > 0 ? 1 : -1;
     }
     usort($filearray, 'mysort');
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.