Log in

View Full Version : Resolved array sorting problem



james438
11-23-2009, 08:44 AM
Any ideas on how to sort the following array so that if it ends in "--DIRECTORY" it will be placed in the beginning of the array and the "--DIRECTORY" listings will also be sorted a-z case insensitive as well. For example


$a=array('that--DIRECTORY','next--DIRECTORY','big','this','dad--DIRECTORY','fruit','apple--DIRECTORY');

will be sorted to look like:


$a[0]=apple--DIRECTORY
$a[1]=dad--DIRECTORY
$a[2]=next--DIRECTORY
$a[3]=that--DIRECTORY
$a[4]=big
$a[5]=fruit
$a[6]=this

james438
11-23-2009, 09:59 AM
Looking around I found this thread http://www.dynamicdrive.com/forums/showthread.php?t=16853&highlight=array+sort and tweaked the code to look like this:


<?php
function parseMD($date) {
$end = substr($date,-9);
$begin = substr($date,0,20);
return array(
'm' => $end,
'd' => $begin
);
}
function compareMD($a, $b) {
$da = parseMD($b);
$db = parseMD($a);
$ret = 0;

foreach(array('d', 'm') as $k)
if($da[$k] < $db[$k])
$ret = 1;
else if($da[$k] > $db[$k])
$ret = -1;
return $ret;
}
$ab=array('that--DIRECTORY','next--DIRECTORY','big','this','dad--DIRECTORY','fruit','apple--DIRECTORY');

usort($ab, "compareMD");
print_r($ab);
?>

However, now the array looks like this:

Array ( [0] => big [1] => fruit [2] => this [3] => apple--DIRECTORY [4] => dad--DIRECTORY [5] => next--DIRECTORY [6] => that--DIRECTORY )
which is really close, but the "--DIRECTORY" listings are placed second as opposed to first. I really do not understand user defined functions (http://us.php.net/manual/en/function.create-function.php) at all.

I never did learn how to create functions. user defined functions may be easy compared to the PHP library as a whole, but it is like organic chemistry to me.

james438
11-24-2009, 12:01 AM
Well, after a few hours of staring at the functions I last posted, reading up on different functions and trying out different things I was not able to figure much out.

But I was able to come up with the following, which does what I want:


<?php
function tag($a, $b) {return (substr($a,-9) > substr($b,-9));}
$a=array('that--DIRECTORY','next--DIRECTORY','big','this','dad--DIRECTORY','fruit','apple--DIRECTORY','aaaaaaaaaaaa');
usort($a,'tag');
foreach ($a as $k => $v)
{
$pos = strpos($v, '--DIRECTORY');
if ($pos !== false)
{
$pos=$k;
break;
}
}

foreach ($a as $k => $v)
{
$pos1 = strpos($v, '--DIRECTORY');
if ($pos1 !== false)
{
$pos2++;
}
}

$begin=array_splice($a,$pos,$pos2);
natcasesort($begin);
$end=$a;
natcasesort($end);
$a=array_merge($begin,$end);
if ($pos===false) natcasesort($a);
print_r($a);
?>
produces

Array ( [0] => apple--DIRECTORY [1] => dad--DIRECTORY [2] => next--DIRECTORY [3] => that
--DIRECTORY [4] => aaaaaaaaaaaa [5] => big [6] => fruit [7] => this )
I am sure this can be cleaned up and made more efficient, but it works.

traq
11-24-2009, 02:35 AM
You're thinking too hard. (and you have some syntax problems in your code above.) Try this:

<?php

// define your list
$a = array(
'that--DIRECTORY',
'next--DIRECTORY',
'big',
'this',
'dad--DIRECTORY',
'fruit',
'apple--DIRECTORY'
);
// call the function and pass your list to it
$sortedList = DIRsort($a);

function DIRsort($list){

// temp array to hold values with "--DIRECTORY"
$dirSubList = array();
// temp array to hold non-"--DIRECTORY" values
$subList = array();

// loop through each item in array
foreach($list as $li){
// if "--DIRECTORY" is found, place value in $dirSubList array
if(strstr($li, '--DIRECTORY')){ $dirSubList[] = $li; }
// if not, place in $subList array
else{ $subList[] = $li; }
}

// sort each array alphabetically
sort($dirSubList);
sort($subList);
// recombine the two arrays
$List = array_merge($dirSubList, $subList);

// send the properly sorted list back to the script
return $List;

}

?>
Tested. var_dump($sortedList); outputs:


array(7) {
[0]=>
string(16) "apple--DIRECTORY"
[1]=>
string(14) "dad--DIRECTORY"
[2]=>
string(15) "next--DIRECTORY"
[3]=>
string(15) "that--DIRECTORY"
[4]=>
string(3) "big"
[5]=>
string(5) "fruit"
[6]=>
string(4) "this"
}

james438
11-24-2009, 02:55 AM
Thank you for that and especially for the extensive notation. I'll be studying it for a bit. User defined functions is my php achilles heel.

P.S. If you look at the post right before yours you will see the solution that I came up with. I edited the post to remove the errors. Yours is obviously better and easier to understand though.

traq
11-24-2009, 03:28 AM
You're welcome! I think you were on the same track. I'm not sure about some of it though.

user-defined functions are well worth it. once you get them mastered, learn how to build classes. good luck!