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

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • luftikus143
    New Member
    • Jan 2007
    • 97

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

    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!
  • ronverdonk
    Recognized Expert Specialist
    • Jul 2006
    • 4259

    #2
    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:

    Comment

    • luftikus143
      New Member
      • Jan 2007
      • 97

      #3
      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!

      Comment

      • ronverdonk
        Recognized Expert Specialist
        • Jul 2006
        • 4259

        #4
        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:

        Comment

        • luftikus143
          New Member
          • Jan 2007
          • 97

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

          So here is the result:
          Code:
          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

          Comment

          • ronverdonk
            Recognized Expert Specialist
            • Jul 2006
            • 4259

            #6
            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($arra y[, $key, $order, $type]...)
            function multisort($arra y) {
            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(multiso rt($a, "0", false, 0));
            echo('</pre>');
            ?> [/php]
            Ronald :cool:

            Comment

            • luftikus143
              New Member
              • Jan 2007
              • 97

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

              Comment

              • luftikus143
                New Member
                • Jan 2007
                • 97

                #8
                Originally posted by luftikus143
                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...

                Comment

                • luftikus143
                  New Member
                  • Jan 2007
                  • 97

                  #9
                  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":

                  Code:
                  Array
                  (
                      [5] => Array
                          (
                              [0] => 10.6
                              [1] => 8.4
                              [2] => 4.2
                          )
                  
                      [2] => Array
                          (
                              [0] => 5.9
                              [1] => 4.9
                              [2] => 6.3
                          )
                  
                      [1] => Array
                          (
                              [0] => 4.4
                              [1] => 4.3
                              [2] => 5.4
                          )
                  
                      [6] => Array
                          (
                              [0] => 3.6
                              [1] => 8.2
                              [2] => 4.2
                          )
                  
                      [4] => Array
                          (
                              [0] => 3.1
                              [1] => 3.2
                              [2] => 2.9
                          )
                  
                      [0] => Array
                          (
                              [0] => 1.1
                              [1] => 5.9
                              [2] => 
                          )
                  
                      [7] => Array
                          (
                              [0] => 1
                              [1] => 2.6
                              [2] => 2.4
                          )
                  
                      [3] => Array
                          (
                              [0] => 
                              [1] => 3.4
                              [2] => 11
                          )
                  
                  )
                  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?

                  Comment

                  Working...