Jump to content

Welcome to AstaHost - Dear Guest , Please Register here to get Your own website. - Ask a Question / Express Opinion / Reply w/o Sign-Up!

Toggle shoutbox Shoutbox Open the Shoutbox in a popup

@  yordan : (21 April 2014 - 09:11 PM) Hey, Ritesh, Did You Hear Me?
@  yordan : (14 April 2014 - 05:28 PM) By The Way, This Could Be An Interesting Subject For A Topic, What About Posting This Question? Let's See If Other People Have The Same Feeling Concerning Bootlists!
@  yordan : (13 April 2014 - 09:36 AM) Boot Order : Cd, [Usb,] Hard Drive :D
@  yordan : (11 April 2014 - 07:23 PM) I Simply Let The Bios Do That
@  Ritesh : (11 April 2014 - 10:23 AM) Is It Possible To Launch Fedora Live Cd Or Installation Disk From Hard Drive On Windows Platform Using Grub Mbr File.
@  Ritesh : (11 April 2014 - 10:21 AM) No U Are Not.. Btw.. I Have Question For You.
@  yordan : (10 April 2014 - 08:02 AM) You Are Partially Right.
I Was Not.
Nevertheless, I Am Again :)
@  Ritesh : (09 April 2014 - 07:33 PM) :P
@  Ritesh : (09 April 2014 - 07:33 PM) I Think U R Not..
@  yordan : (09 April 2014 - 09:28 AM) I'm The Master Of The Shoutbox!
@  yordan : (05 April 2014 - 10:32 PM) He-He
@  Ritesh : (04 April 2014 - 06:59 PM) Ha Ha Ha ....
@  yordan : (04 April 2014 - 11:15 AM) Welcome Back, Starscream!
@  yordan : (03 April 2014 - 02:31 PM) And I Hope That He Will Come Back Soon :)
@  yordan : (01 April 2014 - 02:53 PM) Nice, Ritesh Came, I'm Not Home Alone Today.
@  Ritesh : (01 April 2014 - 08:51 AM) Oh!!! Poor Dear Yordan..
@  yordan : (31 March 2014 - 10:02 AM) I'm A Poor Lonesome Cow-Boy
@  yordan : (27 March 2014 - 02:22 PM) He Is Unpatient Due To His Patients!
@  Ritesh : (27 March 2014 - 10:46 AM) :(
@  Ritesh : (27 March 2014 - 10:46 AM) He Is Busy With His Patients.

- - - - -

Day_sort() Sort an array by day

1 reply to this topic

#1 Guest_mastercomputers_*

  • Guests

Posted 11 October 2006 - 01:16 PM

If it wasn't for vujsa and HandyPHP.com, or the discussion over at Trap17.com.

I would have had no reason to make this function more flexible and act more like a PHP function. So this is why I have done this, though I would have contributed it to Trap17.com, I was not a member over there nor does it benefit me in anyway. None of the code has been taken from HandyPHP.com. It's a complete rewrite in a way I felt works better for most people, it could do with better error handling though, but that can be discussed here if needs be.

So here it is:


(To use this function needs: PHP 4 or PHP 5. It is not part of PHP)
day_sort -- Sort an array by day of the week.


bool day_sort ( array &array [, int sort_flag[, int order_flag ]] )

This function sorts an array that is prefixed by day of the week from Sunday to Monday including abbreviated days when function has completed.

[tab][/tab]Note: This function assigns new keys for the elements in array. It will remove any existing keys you may have assigned, rather than just reordering the keys.

Returns TRUE on success or FALSE on failure.

Function day_sort() source

function day_sort(&$array = NULL, $sort_flag = SORT_REGULAR, $order_flag = SORT_ASC){	if (!defined('__FUNCTION__'))	{		define('__FUNCTION__', 'day_sort');	}	$argc = func_num_args();	if ($argc < 1)	{		echo "\n".'<p><strong>Warning:</strong> <em>'.__FUNCTION__.'()</em> expects at least <em>1</em> parameter, <em>'.$argc.'</em> given.</p>'."\n";		return false;	}	if (!is_array($array))	{		echo "\n".'<p><strong>Warning:</strong> <em>'.__FUNCTION__.'()</em> expects parameter <em>1</em> to be an <em>array</em>, <em>'.gettype($array).'</em> given.</p>'."\n";		return false;	}	if (count($array) < 2)	{		return true;	}	if (!is_int($sort_flag))	{		echo "\n".'<p><strong>Warning:</strong> <em>'.__FUNCTION__.'()</em> expects parameter <em>2</em> to be <em>integer</em>, <em>'.gettype($sort_flag).'</em> given.</p>'."\n";		return false;	}	else	{		switch($sort_flag)		{			// For PHP > 4.3			// case SORT_LOCALE_STRING:			// case 5:			case SORT_STRING:			case 2:			case SORT_NUMERIC:			case 1:			case SORT_REGULAR:			case 0:				break;			default:				$sort_flag = 0;				break;		}	}	if (!is_int($order_flag))	{		echo "\n".'<p><strong>Warning:</strong> <em>'.__FUNCTION__.'</em> expects parameter <em>3</em> to be <em>integer</em>, <em>'.gettype($order_flag).'</em> given.</p>'."\n";		return false;	}	else	{		switch($order_flag)		{			case SORT_ASC:			case 4:			case SORT_DESC:			case 3:				break;			default:				$order_flag = 4;				break;		}	}	if ($argc > 3)	{		echo "\n".'<p><strong>Warning:</strong> <em>'.__FUNCTION__.'()</em> expects at most <em>3</em> parameters, <em>'.$argc.'</em> given.</p>'."\n";		return false;	}	$days_pattern = array('/^sun(day)?/i','/^mon(day)?/i','/^tue(sday)?/i','/^wed(nesday)?/i','/^thu(rsday)?/i','/^fri(day)?/i','/^sat(urday)?/i');	$replacements = array(' ! ',' !! ',' !!! ',' !!!! ',' !!!!! ',' !!!!!! '," !!!!!!! ");	$tmp_array = array_map('ltrim', $array);	$tmp_array = array_values($tmp_array);	for ($i = 0, $j = count($days_pattern); $i < $j; $i++)	{		for ($k = 0, $m = count($tmp_array); $k < $m; $k++)		{			if (preg_match($days_pattern[$i],$tmp_array[$k]))			{				$replaced = preg_replace($days_pattern, $replacements, $tmp_array);				break;			}		}	}	if (!array_multisort($replaced, $order_flag, $sort_flag, $array))	{		return false;	}	$array = array_values($array);	return true;}

[tab][/tab]Note: This function has not been tested with the int sort_flag being set yet. It is only there for when I expand this function.

Example 1. day_sort() example

$days_to_sort = array('tuesday34','nottoday','fri382','monday1234','thu384','string_key' => 'Sunday23402', 'su32');
$tmp_str = '';
foreach($days_to_sort as $key => $value)
	$tmp_str .= 'days_to_sort['.$key.'] = '.$value."\n";
echo $tmp_str;

The above example will output:

days_to_sort[0] = Sunday23402
days_to_sort[1] = monday1234
days_to_sort[2] = tuesday34
days_to_sort[3] = thu384
days_to_sort[4] = fri382
days_to_sort[5] = nottoday
days_to_sort[6] = su32

The days_to_sort have been sorted by Sunday to Saturday order and those which aren't day names get sorted after.

The optional second parameter sort_flag may be used to modify the sorting behavior. For more information on sort_flag please visit PHP: sort - Manual

The option third parameter order_flag may be used to modify the order behavior. For more information on order_flag please visit PHP: array_multisort - Manual

Be careful when sorting arrays with mixed typed values because day_sort() can produce unpredictable results.

About the code

It has been brought to my attention that this code maybe hard for everyone to follow so I will go over it.

function day_sort(&$array = NULL, $sort_flag = SORT_REGULAR, $order_flag = SORT_ASC)

This is where we have created our function, it takes 3 parameters but only the first parameter is needed and it must be a reference to an array which means the array must come from a variable e.g. $var = array('something'); day_sort($var); because we are altering the variable itself and returning TRUE on success or FALSE on failure, so we can also check whether this function performed correctly or not.

		define('__FUNCTION__', 'day_sort');

__FUNCTION__ did not exist till PHP 4.30, I've tried my best to make sure this is PHP 4 compatible, this is just a simple workaround for this.

$argc = func_num_args();

Stores the number of arguments sent to the function. $argc stands for argument count.

From then on the code should be self explanatory, it's just simple error checking until we get to the switch statements which I'll explain. If you read the Warning messages, it'll explain more about what those checks do.

Brief explanation:
  • Must have at least 1 argument.
  • First parameter must be an array
  • If there's only 1 item in the array, there's no reason to sort.
  • Second parameter must be an integer
  • Third parameter must be an integer
  • If there's more than 3 parameters, we've sent too many arguments.
Now all the switch does is make sure that the integers correspond with what has been defined already, and if not, we give it the default values SORT_REGULAR and SORT_ASC.

$days_pattern = array('/^sun(day)?/i','/^mon(day)?/i','/^tue(sday)?/i','/^wed(nesday)?/i','/^thu(rsday)?/i','/^fri(day)?/i','/^sat(urday)?/i');

This creates our days_pattern, which is case-insensitive. It works with either 3 letter abbreviated day names or whole names. e.g. Sun or tuesday, etc.

$replacements = array(' ! ',' !! ',' !!! ',' !!!! ',' !!!!! ',' !!!!!! ',' !!!!!!! ');

This is what we will replace our day names with, I chose this characters because they come before any alphanumeric character and it's just after space, I also use space to make sure it's seperated for easier ordering as I left trim everything in the array to remove space characters.

$tmp_array = array_map('ltrim', $array);

Removes leading space characters and stores the results in a temporary array, since we passed an array by reference if we changed it, those changes will affect the referenced array, so we don't want to change it till it's completed the function.

$tmp_array = array_values($tmp_array);

Changes all array names/keys to numbers, maintaining the value positions.

Next we have the for loop with another for loop nested inside, what happens is we create an array called $replaced, which changes prefixed days to one of the corresponding replacements, if no replacement is need, it will just store the string without changes.

if (!array_multisort($replaced, $order_flag, $sort_flag, $array))
		return false;

This sorts the array, and updates $array, if it fails, no changes are made and it returns false.

$array = array_values($array);

Does the same as explained in $tmp_array = array_values($tmp_array); but for our referenced $array.

Function completed true is returned and the array we passed has been updated.

Things to discuss

Should array keys be preserved?

If so, it's possible to do this, though I may need to add another parameter to the function to allow it.

Should prefixed day strings and non-day strings in the array be seperated or mixed?

The main reason why I'm thinking this is the ordering, imagine the days at the top SORT_ASC ordered, then the non-days after it SORT_ASC ordered, that's how it would be with just setting SORT_ASC.

But what if you would like to reverse the ordering for days only, or non-days? and place days either before the non-days or after the non-days. Maybe showing an example would explain this better but only if it's requested will I do that.

And my last idea is, should we order it even further so that abbreviated names come before whole names, etc. Doesn't matter, what I mean is, should they be grouped seperately too, and can also be ordered seperately?

Well thanks for the opportunity to do this, and thanks to vujsa, Trap17.com and HandyPHP.com.



#2 vujsa


    Absolute Newbie

  • Members
  • 888 posts
  • Gender:Male
  • Location:Indianapolis, Indiana, USA (Midwest)
  • myCENTs:35.43

Posted 11 October 2006 - 10:45 PM

This is a really nice function mastercomputers.

I'm kind of glad to see that your base method is generally the same as mine. What I mean to say is that your central sorting method is done with pattern replacements and then sort the original array by the values of the second array. Other than that, it is completely different except that it returns a nicely sorted array of data.

You pointed out a flaw in my original code which in certain situations would have missorted the data. I have modified the code to perform more consistantly but the numeric method I used could still cause problems.

I like the $days_pattern method that you used with the regular expressions which greatly reduces the overall size of both the search and replace arrays which should generally increase the effiecency of the script.

You had asked about whether or not to preserver array keys and allow for sub-sorting. I'm not sure what is best here. Adding further flexability to the script could also make it more difficult for users to use the function. Since more flexability usually results in additional parameters being entered by the user or at least more options for the user to consider, the user could be overwhelmed by options.

It could be argued that the user could run additional functions on the array after the function is done but if the user was capable of these operations then they should be able to manipulate a more complex function.

I can't believe that in just 2 days this piece of code has been rewritten 4 times on 4 different websites.
BuffaloHelp wrote a script that perform this action which I rewrote for him to make it more efficient. I then modified that script to be more flexable and eventually converted it to a function which I submitted to Handy PHP. This newest version again has increased the effciency and effectiveness of the task.

So I guess this is the 5th version or 3rd generation of the idea. Things happen so fast on the web. :P

Anyway, I'm glad to see that an interest has been taken in this subject. I guess Handy PHP has managed to fulfill one of its goals only after a month of existence.

Thanks for the wonderful post mastercomputers.


Reply to this topic


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users