By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,642 Members | 1,674 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,642 IT Pros & Developers. It's quick & easy.

Sorting Array: $value[$s][$i]

P: 97
Hi there,

how can I sort my array $value[$s][$i]? To be more precise:

Say I have three countries ($s) and each has three values ($i) reprensenting yearly statistics:

DE with 12, 23, 28
FR with 8, 28,15
CH with 10, 20, 30

Now, I want to sort my array by it's highest value. How can I achieve this?

Thanks for any hints!
Jan 22 '07 #1
Share this Question
Share on Google+
8 Replies


ronverdonk
Expert 2.5K+
P: 4,258
You did not specify what part of the array you wanted sorted, so I'll give you this snippet:[php]<?php
$a=array('DE' => array(12, 28, 23),
'FR' => array(8, 28,15),
'CH' => array(30, 20, 10) );
echo '<br><pre>'; print_r($a);
foreach ($a as $key => $val) {
sort($a[$key]);
}
echo '<br><pre>'; print_r($a);
?>[/php]
Ronald :cool:
Jan 22 '07 #2

P: 97
Thanks for the answer.

In principle, as said, I want to sort it by the highest value, be it in the first, second or third (or twentieth) field.

I wonder I have to change my array-type. Cause until now I used two simple loops to fill my variable:
[PHP]for ($s = 0; $s < $numCountries; $s++)
{
... get country name ...

for ($i = 0; $i < $numYears; $i++)
{
$value[$s][$i] = $row[$year[$i]];
}
}[/PHP]

So, I don't have this kind of associative array. Or should/could I build one?

Thanks for your help!
Jan 22 '07 #3

ronverdonk
Expert 2.5K+
P: 4,258
I cannot see how you build your array because I am missing the $value, $year and $row variables/definitions. Make a print_r($value) of the array and show it.

Ronald :cool:
Jan 22 '07 #4

P: 97
Ha, there are so many interesting commands out there, it's incredible. Never heard about the print_r before...

So here is the result:
Expand|Select|Wrap|Line Numbers
  1. Array ( [0] => Array ( [0] => 1.1 [1] => 5.9 [2] => ) [1] => Array ( [0] => 4.4 [1] => 4.3 [2] => 5.4 ) [2] => Array ( [0] => 5.9 [1] => 4.9 [2] => 6.3 ) [3] => Array ( [0] => [1] => 3.4 [2] => 11 ) [4] => Array ( [0] => 3.1 [1] => 3.2 [2] => 2.9 ) [5] => Array ( [0] => 10.6 [1] => 8.4 [2] => 4.2 ) [6] => Array ( [0] => 3.6 [1] => 8.2 [2] => 4.2 ) [7] => Array ( [0] => 1 [1] => 2.6 [2] => 2.4 ) )
And this is the graph (although an older version of the currently developed one): Graph
Jan 23 '07 #5

ronverdonk
Expert 2.5K+
P: 4,258
You actually need 2 sorts here. The 1st one sorts each subarray of 3 entries descending, so the highest is always in entry 0.

The second sort is a multi-sort that sorts the main entry descending on the basis of the subarray entry 0 (highest value in subarray).

The result set shows each entry in the main array, its order based on the highest value anywhere in the sub-array. The result set keeps the key of the main array intact.

Try the following code, assuming the array name $a. The multisort code snippet thanks to remmy.cjb.net in the php documentation at uasort.
[php]<?php
// The default sort order is ascending, and the default sort
// type is strnatcmp.

// function multisort($array[, $key, $order, $type]...)
function multisort($array) {
for($i = 1; $i < func_num_args(); $i += 3) {
$key = func_get_arg($i);

$order = true;
if($i + 1 < func_num_args())
$order = func_get_arg($i + 1);

$type = 0;
if($i + 2 < func_num_args())
$type = func_get_arg($i + 2);

switch($type) {
case 1: // Case insensitive natural.
$t = 'strcasenatcmp($a[' . $key . '], $b[' . $key . '])';
break;
case 2: // Numeric.
$t = '$a[' . $key . '] - $b[' . $key . ']';
break;
case 3: // Case sensitive string.
$t = 'strcmp($a[' . $key . '], $b[' . $key . '])';
break;
case 4: // Case insensitive string.
$t = 'strcasecmp($a[' . $key . '], $b[' . $key . '])';
break;
default: // Case sensitive natural.
$t = 'strnatcmp($a[' . $key . '], $b[' . $key . '])';
break;
}
uasort($array, create_function('$a, $b', 'return ' . ($order ? '' : '-') . '(' . $t . ');'));
}
return $array;
}

echo '<br><pre>PRE-SORT:<br>'; print_r($a);
foreach ($a as $key => $val) {
rsort($a[$key]);
}

echo '<br><pre>SORT 1:<br>'; print_r($a);
// This works like MYSQL 'ORDER BY id DESC, name ASC'
// Note the quoting of string literal keys.
echo '<br><pre>SORT 2:<br>';
print_r(multisort($a, "0", false, 0));
echo('</pre>');
?> [/php]
Ronald :cool:
Jan 23 '07 #6

P: 97
Thanks for the code.

After playing around with it and especially the impacts it has on my graph production code, it seems that it does not have the results I was expecting.

What it does is actually to sort the (yearly) values of a given element (country). So for:

DE with 12, 23, 28
FR with 8, 28,15
CH with 10, 20, 30


the script will do this:

DE with 28, 23, 12
FR with 28,15, 8
CH with 30, 20, 10


and not

DE with 12, 23, 28
CH with 10, 20, 30
FR with 8, 28,15


or

CH with 10, 20, 30
DE with 12, 23, 28
FR with 8, 28,15


depending on which "column" (=year) I sort.
Jan 24 '07 #7

P: 97
Thanks for the code.

After playing around with it and especially the impacts it has on my graph production code, it seems that it does not have the results I was expecting.

What it does is actually to sort the (yearly) values of a given element (country). So for:

DE with 12, 23, 28
FR with 8, 28,15
CH with 10, 20, 30


the script will do this:

DE with 28, 23, 12
FR with 28,15, 8
CH with 30, 20, 10

and not
DE with 12, 23, 28
CH with 10, 20, 30
FR with 8, 28,15

or
CH with 10, 20, 30
DE with 12, 23, 28
FR with 8, 28,15


depending on which "column" (=year) I sort.
Actually, I am not anymore too sure about what is being done or not... The print_r shows that everything has been correctly sorted. But the graph just shows a switch in the years... have to digg into this a bit further...
Jan 24 '07 #8

P: 97
Hmm... I think I know now where the problems lies.

It does - at least if I only use the multisort function in the script above - sort indeed descending for the first value-"colomn":

Expand|Select|Wrap|Line Numbers
  1. Array
  2. (
  3.     [5] => Array
  4.         (
  5.             [0] => 10.6
  6.             [1] => 8.4
  7.             [2] => 4.2
  8.         )
  9.  
  10.     [2] => Array
  11.         (
  12.             [0] => 5.9
  13.             [1] => 4.9
  14.             [2] => 6.3
  15.         )
  16.  
  17.     [1] => Array
  18.         (
  19.             [0] => 4.4
  20.             [1] => 4.3
  21.             [2] => 5.4
  22.         )
  23.  
  24.     [6] => Array
  25.         (
  26.             [0] => 3.6
  27.             [1] => 8.2
  28.             [2] => 4.2
  29.         )
  30.  
  31.     [4] => Array
  32.         (
  33.             [0] => 3.1
  34.             [1] => 3.2
  35.             [2] => 2.9
  36.         )
  37.  
  38.     [0] => Array
  39.         (
  40.             [0] => 1.1
  41.             [1] => 5.9
  42.             [2] => 
  43.         )
  44.  
  45.     [7] => Array
  46.         (
  47.             [0] => 1
  48.             [1] => 2.6
  49.             [2] => 2.4
  50.         )
  51.  
  52.     [3] => Array
  53.         (
  54.             [0] => 
  55.             [1] => 3.4
  56.             [2] => 11
  57.         )
  58.  
  59. )
But when I allocate this variable to the graphing code, it still counts the first part of the array from 1 to x, even though [3] for example is now on the latest position.

How can I convert the above result into a new variable with the then-current order?
Jan 31 '07 #9

Post your reply

Sign in to post your reply or Sign up for a free account.