Jump to content

Sort a two dimensional array.


penguincentral

Recommended Posts

Hi.  I've set up a two dimensional array that reads as follows:

 

$modifiedData = array( array($arrCollingwoodStart[0], $numCollingwoodForTotal, $numCollingwoodAgainstTotal, $numCollingwoodPercentage, $numCollingwoodPointsTotal),
                 array($arrAdelaideStart[0], $numAdelaideForTotal, $numAdelaideAgainstTotal, $numAdelaidePercentage, $numAdelaidePointsTotal),
                array($arrBrisbaneStart[0], $numBrisbaneForTotal, $numBrisbaneAgainstTotal, $numBrisbanePercentage, $numBrisbanePointsTotal),
                array($arrCarltonStart[0], $numCarltonForTotal, $numCarltonAgainstTotal, $numCarltonPercentage, $numCarltonPointsTotal));

 

Each array within represents one row of a table.  I need to sort the arrays descending by the variables that end in "PointsTotal", and then by the variables that end in "Percentage".  As of yet I haven't worked out how to sort the array out as I want to.  Have I set up this array correctly? And if so, how do I peform the sort as I've described?

 

If anyone can help me out, that would be greatly appreciated :)

Link to comment
Share on other sites

You'll need to use the user sort functions: usort (or uasort if you wish to maintain associativity)

 

Ok.  I now have this code:

 

$modifiedData = array( array($arrCollingwoodStart[0], $numCollingwoodForTotal, $numCollingwoodAgainstTotal, $numCollingwoodPercentage, $numCollingwoodPointsTotal),
                 array($arrAdelaideStart[0], $numAdelaideForTotal, $numAdelaideAgainstTotal, $numAdelaidePercentage, $numAdelaidePointsTotal),
                array($arrBrisbaneStart[0], $numBrisbaneForTotal, $numBrisbaneAgainstTotal, $numBrisbanePercentage, $numBrisbanePointsTotal),
                array($arrCarltonStart[0], $numCarltonForTotal, $numCarltonAgainstTotal, $numCarltonPercentage, $numCarltonPointsTotal));

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

uasort($modifiedData, 'cmp');

echo "<br /><br />";
print_r($modifiedData);

 

I'm sorry if i'm asking a newbie question here, but how do i change it so it sorts based on the last value as well as in a descending order?

Link to comment
Share on other sites

here is a class i wrote to sort two dimensional arrays. it differs slightly from the uasort function as it allows you to specify the element/s to sort by. See if it helps.

 

<?php

$stock = array(array("id" => 1,"item" => "hat", "number" => 2,	"price" => 15),
			array("id" => 5,"item" => "shoes", "number" => 1,	"price" => 50),
			array("id" => 4,"item" => "pants", "number" => 5,	"price" => 50),
			array("id" => 3,"item" => "tie", "number" => 5,	"price" => 30));

$sort = new multiSort();

//rcmp function sort be ascending order
//cmp sorts by descending order
//can also be used like so (specifying the index of the array) - print_r ($sort->sortArray($stock,'2','3','rcmp','rcmp'));

print_r ($sort->sortArray($stock,'number','price','rcmp','rcmp'));


//////////////////////////////////////////////////////

class multiSort {

function sortArray($array,$parameter,$secondParameter,$_function, $secondFunction) { return $this->_uasort($array,$_function, $secondFunction,$parameter,$secondParameter); }

function cmp ($a, $b, $p) { return (strcmp ($a[$p],$b[$p]));}

function rcmp ($a, $b, $p) { return -1 * (strcmp ($a[$p],$b[$p]));}

function _uasort($array,$func,$secFunc,$param,$secParam) {
	for($i=0;$i<sizeof($array);$i++) {	//loop through array
		$tmp = $i;
		for($j=$tmp;$j<sizeof($array);$j++) {	//loop through each array element of the main array
			$result = $this->$func($array[$tmp],$array[$j],$param);	//call compare function
			if($result == -1) {		//if the first value is less than the second
				$array = $this->arraySwap($array,$tmp,$j);	//swap the arrays over
				$tmp = $j;		//reset the temp variable
			} elseif($result == 0) {	//if the values are even
				if($secParam != '' && $secFunc != '') {		//if the second level sort variables have been set
					$secResult = $this->$secFunc($array[$tmp],$array[$j],$secParam);	//call the compare function
					if($secResult == -1) {	//if the first value is less than the second
						$array = $this->arraySwap($array,$tmp,$j);	//swap the arrays over
						$tmp = $j;	//reset the temp variable
					}
				}
			}
		}
	}	
	return $array;
}

function arrayswap($arr, $src, $dst) { 
	$tmp = $arr[$dst]; 
	$arr[$dst] = $arr[$src]; 
	$arr[$src] = $tmp; 
	return $arr; 
} 
}
//////////////////////////////////////////////////////////
?>

Link to comment
Share on other sites

Hi

 

Quick edit:-

 

<?php

$modifiedData = array( array($arrCollingwoodStart[0], $numCollingwoodForTotal, $numCollingwoodAgainstTotal, $numCollingwoodPercentage, $numCollingwoodPointsTotal),
                 array($arrAdelaideStart[0], $numAdelaideForTotal, $numAdelaideAgainstTotal, $numAdelaidePercentage, $numAdelaidePointsTotal),
                array($arrBrisbaneStart[0], $numBrisbaneForTotal, $numBrisbaneAgainstTotal, $numBrisbanePercentage, $numBrisbanePointsTotal),
                array($arrCarltonStart[0], $numCarltonForTotal, $numCarltonAgainstTotal, $numCarltonPercentage, $numCarltonPointsTotal));

function cmp($a, $b) {
    if ($a[0] == $b[0]) {
	if ($a[4] == $b[4]) {
		return 0;
	}
	return ($a[4] > $b[4]) ? -1 : 1;
    }
    return ($a[0] < $b[0]) ? -1 : 1;
}

uasort($modifiedData, 'cmp');

echo "<br /><br />";
print_r($modifiedData);
?>

 

All the best

 

Keith

Link to comment
Share on other sites

hmmm cant edit my original post??

 

Anyway - Sorry, i should have given you an example of how to use this class with what you have written: so it would go something like this:

 

<?php
$modifiedData = array( array($arrCollingwoodStart[0], $numCollingwoodForTotal, $numCollingwoodAgainstTotal, $numCollingwoodPercentage, $numCollingwoodPointsTotal),
                 array($arrAdelaideStart[0], $numAdelaideForTotal, $numAdelaideAgainstTotal, $numAdelaidePercentage, $numAdelaidePointsTotal),
                array($arrBrisbaneStart[0], $numBrisbaneForTotal, $numBrisbaneAgainstTotal, $numBrisbanePercentage, $numBrisbanePointsTotal),
                array($arrCarltonStart[0], $numCarltonForTotal, $numCarltonAgainstTotal, $numCarltonPercentage, $numCarltonPointsTotal));

//create instance of class
$sort = new multiSort();

//this will return the sorted array to $modifiedData (array will be sorted descending for both points and percentage)
$modifiedData = $sort->sortArray($modifiedData ,'4','3','cmp','cmp');


//the class code can go here or in another php page its up to you.
?>

Link to comment
Share on other sites

hmmm cant edit my original post??

 

Anyway - Sorry, i should have given you an example of how to use this class with what you have written: so it would go something like this:

 

<?php
$modifiedData = array( array($arrCollingwoodStart[0], $numCollingwoodForTotal, $numCollingwoodAgainstTotal, $numCollingwoodPercentage, $numCollingwoodPointsTotal),
                 array($arrAdelaideStart[0], $numAdelaideForTotal, $numAdelaideAgainstTotal, $numAdelaidePercentage, $numAdelaidePointsTotal),
                array($arrBrisbaneStart[0], $numBrisbaneForTotal, $numBrisbaneAgainstTotal, $numBrisbanePercentage, $numBrisbanePointsTotal),
                array($arrCarltonStart[0], $numCarltonForTotal, $numCarltonAgainstTotal, $numCarltonPercentage, $numCarltonPointsTotal));

//create instance of class
$sort = new multiSort();

//this will return the sorted array to $modifiedData (array will be sorted descending for both points and percentage)
$modifiedData = $sort->sortArray($modifiedData ,'4','3','cmp','cmp');


//the class code can go here or in another php page its up to you.
?>

 

thanks that makes more sense.  i'll put the class code in the same php page, but does the class code need to go before or after the code above?

 

Keith, i tried your code out but i wasn't successful with it :(

Link to comment
Share on other sites

yeah sorry about that  :D

 

it wont matter where you put the class code, it will still work. I like to put it at the bottom cause otherwise i find you have to scroll through it to get to other stuff when developing.

 

thanks. i've put the code in and it seems to be working fine (barring a few issues with my other code which i've managed to sort out).  Thanks for your help :)

Link to comment
Share on other sites

Alittle late I guess but you can also try using the array_multisort() function

http://us2.php.net/manual/en/function.array-multisort.php

 

Below should work on sorting 2keys on the 2d array that was given by alt_f4..  //sorry ahead of time for bad commenting..

<?php
//multi dimensional array sort - 2 keys
//args :
//atmp = array to sort
//$key1 $key2 ordered by priority - ie first key has presidence over second key
//$key1order $key2order = array of sorting order flags. Should correspond to key array otherwise if blank, assume SORT_ASC
/*
Sorting order flags:
SORT_ASC - Sort in ascending order
SORT_DESC - Sort in descending order
Sorting type flags: //not used
SORT_REGULAR - Compare items normally
ORT_NUMERIC - Compare items numerically
SORT_STRING - Compare items as strings
*/

function multi_array_2key_sort($atmp, $key1, $key2, $key1order=SORT_ASC, $key2order=SORT_ASC){
	foreach($atmp as $atmp2){
		$sort1[] = $atmp2[$key1];
		$sort2[] = $atmp2[$key2];
	}

	if(array_multisort($sort1, $key1order, $sort2, $key2order, $atmp)){
		return $atmp;
	}else{ //debug else...
		//print "FAIL";
		return $atmp;
	}
}//function multi_array_2key_sort

//example
$stock = array(array("id" => 1,"item" => "hat", "number" => 2,	"price" => 15),
			array("id" => 5,"item" => "shoes", "number" => 1,	"price" => 50),
			array("id" => 4,"item" => "pants", "number" => 5,	"price" => 50),
			array("id" => 3,"item" => "tie", "number" => 5,	"price" => 30));
$stock = multi_array_2key_sort($stock, 'number', 'price');

?>

Link to comment
Share on other sites

I have another related issue.  I have serialised the array and saved it to a file.  However I am having trouble with unserialising it and returning it into array form on another page.  I've used this line of code on my second php file:

 

var_dump(unserialize(file_get_contents('Ladder.txt')));

 

however it outputs "bool(false)" on the page.  the text file reads correctly though.  Below are the links to my code:

 

index.php: http://pastebin.ca/1619248

index1.php: http://pastebin.ca/1619251

 

if anyone can help me that would be great :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.