Page 1 of 1

Sorting Array in PHP

Posted: Thu Jul 08, 2010 10:58 am
by Some1Better-er
Hi all. New both to the forum and to PHP so with 2 strikes already against me, I'll not try to add being terribly annoying as the third. That being said, I'm using a bit of code I wrote (albeit very poorly) to try to grab a folder of pictures as my directory, then sort, and eventually output those pictures. I haven't quite gotten to the output yet, because I'm having trouble with the sorting. The pictures are sorted by name, all in a standard format, for example, today the 8th of July would read 20100708-001. If multiple pictures were used, the -001 becomes -002, then -003, etc. I need the pictures in the most recent order first, which I could just typically use an arsort for - the catch is I want them in order for that day. For example, if I had pictures from the 2,4,5, and 8th of July, I would want them in 8,5,4,2 order, but if I had 3 pictures from the 8th, I would want them in 20100708-001, 20100708-002, 20100708-003, 20100705-001, 20100704-001, and finally 20100702-001. To accommodate this I tried using a multidimensional array with the first 8 characters being sorted by a standard sort, being somewhat modified by the second sort regarding characters 10-12. Didn't quite get it working, and as I said, the output isn't really coded yet. Anyway, hope I haven't been to wordy, and thanks for the help in advance. Here's what I have so far with obsolete bits commented out until I decide to do it for good or re-add them:

Code: Select all

<?php

$photo_Array = array();

if ($handle = opendir('/Users/web/Documents/Program_Photos')) {
    //echo "Directory handle: $handle\n";
    //echo "Files:\n";
	
    /*Loops over the directory. */
	while (false !== ($file = readdir($handle))) {
		//echo "$file\n";
		
		$first_date = substr($file, 0, 8);
		$second_date = substr($file, 10, 12);
		
		if (isset($prev_file) && $first_date == $prev_file) {
			$photo_Array[$first_date][] = $file;
		}
		
		elseif ($first_date != $prev_file) {
			//$prev_file = $first_date;
			$photo_Array[$first_date][] = $file;
		}
		
		//$photo_Array[] = $file;
	}
		$prev_file = $first_date;
}
	
	arsort($photo_Array);
//	echo $photo_Array;
	var_dump($photo_Array);

	closedir($handle);
?>
The output I get with the vardump looks like the following.

array(5) { [20100702]=> array(2) { [0]=> string(16) "20100702-001.jpg" [1]=> string(16) "20100702-002.jpg" } [20100701]=> array(2) { [0]=> string(16) "20100701-001.jpg" [1]=> string(16) "20100701-002.jpg" } [20100604]=> array(1) { [0]=> string(16) "20100604-002.jpg" } [".."]=> array(1) { [0]=> string(2) ".." } ["."]=> array(1) { [0]=> string(1) "." } }

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 12:27 pm
by Jade

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 12:39 pm
by AbraCadaver
natsort() is probably easier and should work well for these values.

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 12:50 pm
by Jade
AbraCadaver wrote:natsort() is probably easier and should work well for these values.
Sweet, I didn't know there was such a thing but then again most of the sorting i do is with objects that have objects within them... nasty sorting stuff. I'll keep that in mind in the future :D

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 1:13 pm
by Some1Better-er
That would work well for both? I can typically get the sort implemented for 1 sorting condition. i.e. I get the strings sorted in reverse order but have trouble trying to get the -xxx suffixes if you will sorted in correct order. My current code as is sorts all of the suffixes within each date, and groups same dates together, but doesn't necessarily have the dates themselves in order. I'm not sure how the endings are in order, as I never really use the $second_date variable I've initialized. I suspect there are several issues with my if and elseif, but again, my unfamiliarity with php isn't helping. My current code is

Code: Select all

<?php

$photo_Array = array();

if ($handle = opendir('/Users/web/Documents/Program_Photos')) {
	
	$prev_file = $first_date;
	
    /*Loops over the directory. */
	while (false !== ($file = readdir($handle))) {
		$first_date = substr($file, 0, 8);
		$second_date = substr($file, 10, 12);
		
		if (isset($prev_file) && $first_date == $prev_file) {
			$photo_Array[$first_date][] = $file;
		}
		
		elseif ($first_date != $prev_file) {
			$photo_Array[$first_date][] = $file;
		}
	}
}
	unset($photo_Array['.']);
	unset($photo_Array['..']);
	arsort($photo_Array);
	
	//$photo_Array = substr($str, 10, 12);
	var_dump($photo_Array);
	
	closedir($handle);
?>
Again, with commenting out, mostly on things I tried to get working and typically couldn't. My output is

array(10) { [20110101]=> array(10) { [0]=> string(16) "20110101-001.jpg" [1]=> string(16) "20110101-002.jpg" [2]=> string(16) "20110101-003.jpg" [3]=> string(16) "20110101-004.jpg" [4]=> string(16) "20110101-005.jpg" [5]=> string(16) "20110101-006.jpg" [6]=> string(16) "20110101-007.jpg" [7]=> string(16) "20110101-008.jpg" [8]=> string(16) "20110101-009.jpg" [9]=> string(16) "20110101-010.jpg" } [10000000]=> array(7) { [0]=> string(16) "10000000-001.jpg" [1]=> string(16) "10000000-002.jpg" [2]=> string(16) "10000000-005.jpg" [3]=> string(16) "10000000-009.jpg" [4]=> string(16) "10000000-050.jpg" [5]=> string(16) "10000000-100.jpg" [6]=> string(16) "10000000-999.jpg" } [20100702]=> array(3) { [0]=> string(16) "20100702-001.jpg" [1]=> string(16) "20100702-002.jpg" [2]=> string(16) "20100702-007.jpg" } [20100701]=> array(2) { [0]=> string(16) "20100701-001.jpg" [1]=> string(16) "20100701-002.jpg" } [20100805]=> array(1) { [0]=> string(16) "20100805-009.jpg" } [20100604]=> array(1) { [0]=> string(16) "20100604-002.jpg" } [20100101]=> array(1) { [0]=> string(16) "20100101-001.jpg" } [20091125]=> array(1) { [0]=> string(16) "20091125-002.jpg" } [20080119]=> array(1) { [0]=> string(16) "20080119-004.jpg" } [20070830]=> array(1) { [0]=> string(16) "20070830-001.jpg" } }

I added a lot more files because at one point it had everything sorted how I wanted, but I didn't think the code should have been working as it was. Unfortunately I was right. When I remove the arsort, the files are output in perfect order, though I suspect this is due to Mac's tendency to automatically sort files and it's just outputting them as is?

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 1:32 pm
by AbraCadaver
I think this would work:

Code: Select all

while (false !== ($file = readdir($handle))) {
	$photo_Array[] = $file;
}
natsort($photo_Array);
$photo_Array = array_reverse($photo_Array);
But I would probably do this:

Code: Select all

$photo_Array = glob('/Users/web/Documents/Program_Photos/*');
natsort($photo_Array);
$photo_Array = array_reverse($photo_Array);

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 2:39 pm
by Weirdan
natsort() wouldn't work here 'cause OP wanted to sort files in descending order by dates but in ascending order by ordinal numbers. Something like this would probably work:

Code: Select all

$files = glob('/path/to/files/*.jpg', GLOB_NOSORT);
usort($files, function($a, $b) {
    list($a_date, $a_number) = explode('-', basename($a));
    list($b_date, $b_number) = explode('-', basename($b));
    if ($a_date == $b_date) {
        return strcmp($a_number, $b_number); // ascending order by numbers
    } else {
        return -strcmp($a_date, $b_date); // descending order by date
    }
});
var_dump($files);

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 3:51 pm
by Some1Better-er
Awesome... thanks guys. Worked out well, just having trouble getting rid of the full path/filename in my array output.

Re: Sorting Array in PHP

Posted: Thu Jul 08, 2010 3:55 pm
by AbraCadaver
Some1Better-er wrote:Awesome... thanks guys. Worked out well, just having trouble getting rid of the full path/filename in my array output.
basename()

Code: Select all

$photo_Array  = glob('/Users/web/Documents/Program_Photos/*');
natsort($photo_Array);
$photo_Array = array_reverse(array_map('basename', $photo_Array));