Hello,
I have been trying for a while to come up with a function to reverse the keys in an array. See the following example:

[4] => 'value1'
[0] => 'value2'
[1] => 'value3'
[3] => 'value4'
[2] => 'value5'

should become

[0] => 'value1'
[4] => 'value2'
[3] => 'value3'
[1] => 'value4'
[2] => 'value5'

As you can see, the keys have been reversed such that the lowest key value is now the highest.

Can someone help me out?

Thanks!

-Trevor

    The keys are numeric and in the range [0..n-1] for an n-element array?

      I note that not only is the lowest valued key the first key, but that other changes were made as well, e.g., 1,3,2 became 3,1,2. Interestingly, you are willing to break the key-value relations.

      As such, taking the requirement as "lowest key value is now the highest (first)", a possible solution is:

      $keys = array_keys($array);
      $values = array_values($array);
      sort($keys);
      $array = array_combine($keys, $values);

      If the keys 1,3,2 becoming 3,1,2 was a typographical error and you wish to maintain that order, then perhaps:

      $keys = array_keys($array);
      $values = array_values($array);
      // Find lowest valued key.
      $min = 0;
      $count = count($keys);
      for ($i = 1; $i < $count; ++$i)
      {
          if ($keys[$i] < $keys[$min])
          {
              $min = $i;
          }
      }
      // Swap lowest valued key with first key.
      $temp = $keys[0];
      $keys[0] = $keys[$min];
      $keys[$min] = $temp;
      // Map the keys with the values to rebuild the original array.
      $array = array_combine($keys, $values);

      There is a third possibility, namely that you want to shift the lowest valued key to the first position and move those above it down. In that case, you would substitute the swap with:

      $min_value = $keys[$min];
      unset($keys[$min]);
      array_unshift($keys, $min_value);

        This seems to work:

        <?php
        // test data
        $test = array();
        $test[4] = 'value1';
        $test[0] = 'value2';
        $test[1] = 'value3';
        $test[3] = 'value4';
        $test[2] = 'value5';
        // do it
        $temp = $test;
        ksort($temp);
        for($i=0; $i<count($test); $i++)
        {
           $test[$i] = array_pop($temp);
        }
        // show result
        printf("<pre>%s</pre>", print_r($test, 1));
        

        Output:

        Array
        (
            [4] => value2
            [0] => value1
            [1] => value4
            [3] => value3
            [2] => value5
        )
        

          The problem is that ksort() maintains key-value association. The OP's example left the value ordering constant.

            So then the question is, does that matter? (I certainly don't know.) I suspect it's time to find out why in the world the OP wants to do this in the first place. Chances are if we understood the functional requirement that was driving this request, we could find a simpler solution rather than this rather kludgy-looking thing.

              I suspect it's time to find out why in the world the OP wants to do this in the first place. Chances are if we understood the functional requirement that was driving this request, we could find a simpler solution rather than this rather kludgy-looking thing.

              I agree.

                Hi,

                I wrote this before I saw LL's and ND's sensible posts about why do it, but ah well ...

                <?php
                // test data
                $test = array();
                $test[4] = 'value1';
                $test[0] = 'value2';
                $test[1] = 'value3';
                $test[3] = 'value4';
                $test[2] = 'value5'; 
                
                // I'm assuming here (as previously stated) that
                // keys run through all values from 0,1, ..., N-1
                // where N = COUNT(ARRAY)
                $highest_key = count($test) - 1;
                $new_array = array();
                foreach($test as $key => $value){
                	$new_array[$highest_key - $key] = $test[$key];
                }
                
                // to test ...
                echo '<pre>'; var_dump($new_array); echo '</pre>';
                
                // which outputs ...
                
                /*
                array(5) {
                  [0]=>
                  string(6) "value1"
                  [4]=>
                  string(6) "value2"
                  [3]=>
                  string(6) "value3"
                  [1]=>
                  string(6) "value4"
                  [2]=>
                  string(6) "value5"
                }
                */
                ?>

                P.

                  Thanks a lot for all of your help. I used NogDog's solution and it worked great. Thanks again!

                    Still excessive....

                    Take the values out of consideration for the moment - we're not messing with them, only with the keys. We'll use array_keys() and array_values() to separate them into separate (numerically-indexed) arrays. Afterwards, use array_combine() to match the (rearranged) keys back up with the (untouched) values.

                    I lie a little bit; we don't need a separate array for the values - we can just keep using the original array. The values are the same, after all.

                    From here on "the array" is a numerically-indexed array of whatever the keys in the original array were - the result of array_keys($array). "Keys" and "values" refer to the keys and values of this array.

                    1. Find a permutation P that sorts the array.

                    2. Apply P (i.e., sort the array)

                    3. Reverse the array

                    4. Apply the inverse of P.

                    It's easy to find the inverse of P: asort() permutes both the values and the keys of the array so that the values are sorted; the keys were sorted to begin with and now they're not, so sorting them would apply the inverse permutation: in short, ksort() is the opposite of asort().

                    In between we'll want to reverse the keys - without touching the values. It's kind of the same problem, so it has kind of the same solution: separate keys and values, reverse the keys, and recombine.

                    $keys = array_keys($array);
                    
                    asort($keys);
                    $keys = array_combine(array_reverse(array_keys($keys)), $keys);
                    ksort($keys);
                    
                    $array = array_combine($keys, $array);
                    

                    It doesn't matter what the keys are so long as they sort in the usual way. Even if they don't, that's what uasort is for.

                      Write a Reply...