1

What is the best way to group and still maintain order with in groups?

I have an array full of directory paths to files. The array file paths are ordered by the files creation dates.

I want to keep the files in order of creation date but also group them in order of what directory they are in.

Example:

array() {
[1]=> "media/abstract/safe.png"
[2]=> "media/urban/Cross Street 2.png"
[4]=> "media/urban/The Other Side.png"
[5]=> "media/urban/Pharm Child.png"
[6]=> "media/food/DSC_3017.png"
[7]=> "media/abstract/fractal_twins.png"
[9]=> "media/urban/Amsterdam.png"
[11]=> "media/nature/creep.png"
[12]=> "media/urban/obstructed.png"
[13]=> "media/nature/middletown_dreams.png"
}

reordered would look like:

array() {
[1]=> "media/abstract/safe.png"
[2]=> "media/abstract/fractal_twins.png"
[3]=> "media/food/DSC_3017.png"
[4]=> "media/nature/creep.png"
[5]=> "media/nature/middletown_dreams.png"
[6]=> "media/urban/Cross Street 2.png"
[7]=> "media/urban/The Other Side.png"
[8]=> "media/urban/Pharm Child.png"
[9]=> "media/urban/Amsterdam.png"
[10]=> "media/urban/obstructed.png"
}

They are now grouped by their directories, but within their directories they maintain their order relative to one another.

4
  • 2
    Do you mean, keep the keys the same, but alpha sort the values? Commented Jun 8, 2011 at 4:47
  • No, the keys are not important, just the values Commented Jun 8, 2011 at 4:49
  • how did you make the array... from db? Commented Jun 8, 2011 at 4:50
  • yeah, scan directories for images then dump them to db. Commented Jun 8, 2011 at 4:53

1 Answer 1

1

It's not quite straightforward because all of the PHP sorting functions sort by only key or value (as far as I know). But the information needed is in both the key and value. So you'll need to modify the array first, then sort, then change it back to just have the file names.

function sort_files(array &$files)
{
  /* add extended info:
      0: index (original order)
      1: dir name
      2: original file name */
  $i = 0;
  $files = array_map(function($name) use (&$i) {
    return array($i++, dirname($name), $name);
  }, $files);

  /* sort extended array by dir then index */
  usort($files, function($a, $b) {
    $cmp = strcmp($a[1], $b[1]);
    if (!$cmp) $cmp = $a[0] - $b[0];
    return $cmp;
  });

  /* remove extended info from array */
  $files = array_map(function($a) {
    return $a[2];
  }, $files);
}

sort_files($files);

Output:

Array
(
    [0] => media/abstract/safe.png
    [1] => media/abstract/fractal_twins.png
    [2] => media/food/DSC_3017.png
    [3] => media/nature/creep.png
    [4] => media/nature/middletown_dreams.png
    [5] => media/urban/Cross Street 2.png
    [6] => media/urban/The Other Side.png
    [7] => media/urban/Pharm Child.png
    [8] => media/urban/Amsterdam.png
    [9] => media/urban/obstructed.png
)
Sign up to request clarification or add additional context in comments.

1 Comment

That will work, Thank you. I must admit, didn't expect it to be so complex. I guess I was right to ask. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.