Page 1 of 1

Sorting a multidimensional array

Posted: Mon Jun 14, 2010 10:28 am
by MrRSMan
I have the following array:

Code: Select all

$arr = array($nation => array($var1, $var2), $nation => array($var1, $var2), $nation => array($var1, $var2));
I'm using foreach to loop through $nation and for each instance echo $var1 and $var2.

What I now want to do is sort instances of $nation by the order of $var1.

For example:

Code: Select all

array($nation => array($var1 => 1, $var2 => 75), $nation => array($var1 => 2, $var2 => 24), $nation => array($var1 => 3, $var2 => 86))
How can I do this?

Thank you.

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 10:54 am
by Weirdan
http://us2.php.net/array_multisort ('Sorting database results' section)

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 10:55 am
by andyhoneycutt
Your definition of your main array "nation" is a bit odd...Did you mean something like this?

Code: Select all

$nations = array(
  "Nation_One" => array("1", "blah"),
  "Nation_Two" => array("2", "derp")
); 

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 11:05 am
by MrRSMan
Weirdan wrote:http://us2.php.net/array_multisort ('Sorting database results' section)
Thank you Weirdan, but I've already been looking at this and can't make it work.
andyhoneycutt wrote:Your definition of your main array "nation" is a bit odd...Did you mean something like this?

Code: Select all

$nations = array(
  "Nation_One" => array("1", "blah"),
  "Nation_Two" => array("2", "derp")
); 
Yes, sorry- that's right. Could you show me where to go from here please?

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 11:21 am
by andyhoneycutt
Weirdan is correct in saying that array_multisort will work for your current problem. It's not working for you, right now, because your array is mal-formed. Here's what I came up with for you:

Code: Select all

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

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

$nations = array(
  "Nation_Two"   => array("2", "derp"),
  "Nation_One"   => array("1", "blah"),
  "Nation_Four"  => array("4", "deep"),
  "Nation_Three" => array("3", "doop"),
  "Nation_A"     => array("9", "beep"),
  "Nation_B"     => array("0", "boop")
);

// Simple, built-in array sort
array_multisort($nations,SORT_ASC);
print_r($nations);

// Custom sort by first array index of each array element
usort($nations,"my_sort");
print_r($nations);

// Custom sort by second array index of each array element
usort($nations,"my_sort_string");
print_r($nations); 
- The first sort (array_multisort) is ordering by the first index for each index of your nations array.
- The second sort (usort) is doing the same thing, except within the comparison function we are targeting a specific index.
- The third sort (also usort) is doing the same as the other previous usort, but on the second index of the nations array, thereby ordering alphabetically.

With these examples I just wanted to point out that you can get into some pretty creative sorting, there's really no one way to approach your problem.

Hope that helps,
Andy

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 11:48 am
by MrRSMan
Thanks Andy- I think this is just what I need. I'm going to have a play around a drop this into my code- will get back if I need additional help, if you don't mind :)

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 12:01 pm
by andyhoneycutt
Not at all. I'm happy to help.

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 12:09 pm
by MrRSMan
Sorry about this, but say in here:

Code: Select all

function my_sort_string($a,$b)
{
  if ($a[1] == $b[1]) {
    return 0;
  }
  return ($a[1] < $b[1]) ? -1 : 1;
}
...I wanted to make the index variable. How can I achieve something like this?

Code: Select all

$index = 1;

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

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 12:30 pm
by andyhoneycutt
You could always use a global definition:

Code: Select all

// In a top-level include, or at the top of your code...
define('ARRAY_SORT_INDEX', 1);

// ...

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

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 4:26 pm
by Jonah Bron
Use strcmp() to compare the strings, instead. Replace

Code: Select all

usort($nations,"my_sort_string");
With

Code: Select all

usort($nations,"strcmp");

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 5:09 pm
by andyhoneycutt
Jonah Bron wrote:Use strcmp() to compare the strings, instead. Replace

Code: Select all

usort($nations,"my_sort_string");
With

Code: Select all

usort($nations,"strcmp");
Out of the box, this won't work as we're working of the second index of the array ($nations) being passed. You could, however, replace your user comparison function with strcmp.

-Andy

ETA

Code: Select all

//change the string sorting routine...
define('ARRAY_SORT_INDEX_STRING',2);

function my_sort_string($a,$b)
{
  return strcmp($a[ARRAY_SORT_INDEX_STRING], $b[ARRAY_SORT_INDEX_STRING]);
} 

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 5:16 pm
by Jonah Bron
Oh yeah, my bad. Didn't look closely enough. :)

Re: Sorting a multidimensional array

Posted: Mon Jun 14, 2010 5:19 pm
by andyhoneycutt
Better string comparison, though, FTW. Thanks man! =]