Sorting Array in PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Some1Better-er
Forum Newbie
Posts: 3
Joined: Thu Jul 08, 2010 10:43 am

Sorting Array in PHP

Post 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) "." } }
User avatar
Jade
Forum Regular
Posts: 908
Joined: Sun Dec 29, 2002 5:40 pm
Location: VA

Re: Sorting Array in PHP

Post by Jade »

User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Sorting Array in PHP

Post by AbraCadaver »

natsort() is probably easier and should work well for these values.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
Jade
Forum Regular
Posts: 908
Joined: Sun Dec 29, 2002 5:40 pm
Location: VA

Re: Sorting Array in PHP

Post 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
Some1Better-er
Forum Newbie
Posts: 3
Joined: Thu Jul 08, 2010 10:43 am

Re: Sorting Array in PHP

Post 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?
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Sorting Array in PHP

Post 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);
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Sorting Array in PHP

Post 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);
Some1Better-er
Forum Newbie
Posts: 3
Joined: Thu Jul 08, 2010 10:43 am

Re: Sorting Array in PHP

Post by Some1Better-er »

Awesome... thanks guys. Worked out well, just having trouble getting rid of the full path/filename in my array output.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Sorting Array in PHP

Post 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));
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
Post Reply