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
https://forums.phpfreaks.com/topic/177523-sort-a-two-dimensional-array/
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?

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; 
} 
}
//////////////////////////////////////////////////////////
?>

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

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.
?>

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 :(

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 :)

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');

?>

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 :)

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.