3

If I have an associative array like

  • 3 => 50

  • 4 => 12

  • 5 => 45

  • 6 => 89

  • 7 => 5

  • 8 => 1

Now I want to sort only the values of odd keys in ascending order. The output should be:

  • 7 => 5

  • 4 => 12

  • 5 => 45

  • 6 => 89

  • 3 => 50

  • 8 => 1

5
  • 7
    Well I can't see you attempting doing anything, show us the code and we can try to help you. Commented Apr 12, 2016 at 8:00
  • Your question hardly makes any sense. If we are trying to get the odd keys, then how come we are expecting 4 => 12 6 => 89 and 8 => 1 ? 4, 6 and 8 are even. Commented Apr 12, 2016 at 8:25
  • You said, "sort only the values of odd keys in ascending order" but your expected output that you show to us is not like that. Commented Apr 12, 2016 at 8:25
  • If you solve this answer your question because I'm curious on how you'd do this. Commented Apr 12, 2016 at 8:29
  • Related non-duplicate page: php - print even and (sorted) odd numbers of an array Commented Jan 29 at 8:17

4 Answers 4

2

To maintain original keys, you have to first separate even and odd elements:

$odd = $even = array();
array_walk( $array, function( $val, $key ) use ( &$odd, &$even ) { ( $key % 2 ) ? $odd[$key] = $val : $even[$key] = $val; });

Then, sort $odd array:

asort( $odd );

At the end, you reconstruct the array:

$array = array();
while( current( $odd ) || current( $even ) )
{
    if( current( $odd ) )  $array[key($odd)]  = current( $odd );
    if( current( $even ) ) $array[key($even)] = current( $even );
    next( $odd );
    next( $even );
}
print_r( $array );

eval.in demo

Note that your question is a bit ambiguous: it's not totally clear if you base odd/even on key value or key position: this solution consider key values and — trough while and if checks — guarantee that all values are preserved, even if you have more even than odd keys (or vice-versa).

Sign up to request clarification or add additional context in comments.

Comments

1

Try this:

<?php

$array = array(
    3 => 50,
    4 => 12,
    5 => 45,
    6 => 89,
    7 => 5,
    8 => 1
);

$oddElems = array();
$evenElems = array();

$i = 0;
foreach($array as $index => $value)
{
    if($i % 2 == 0)
        $oddElems[$index] = $value;
    else
        $evenElems[$index] = $value;

    $i++;
}

//sort odd elements
asort($oddElems);

$result = array();
while(!empty($oddElems) || !empty($evenElems))
{
    $lastEvenElemKey = array_keys($evenElems, end($evenElems))[0];
    $evenElem = array_pop($evenElems);
    if($evenElem !== null)
        $result[$lastEvenElemKey] = $evenElem;

    $lastOddElemKey = array_keys($oddElems, end($oddElems))[0];
    $oddElem = array_pop($oddElems);
    if($oddElem !== null)
        $result[$lastOddElemKey] = $oddElem;

}
echo '<pre>';

$result = array_reverse($result, true);
print_r($result);

Result is:

Array
(
    [7] => 5
    [4] => 12
    [5] => 45
    [6] => 89
    [3] => 50
    [8] => 1
)

Comments

0

This is how you could do this in PHP, is this what you are looking for ?

$array(3 => 50, 4 => 12, 5 => 45, 6 => 89, 7 => 5, 8 => 1);
function sort_it($array) {
    $final_array[];
    $array_only_odd_keys[];
    $array_only_odd_stuff[];
    $array_only_even_keys[];
    $array_only_even_stuff[];
    foreach($array as $key => $value) {

        if($key & 1) {
            //Key is odd
            array_push($array_only_odd_stuff,  $key => $value);
            array_push($array_only_odd_keys,  $key);
        }
        else {
            // Key is even
            array_push($array_only_even_stuff,  $key => $value);
            array_push($array_only_even_keys,  $key);
        }
    }
    $array_only_odd_keys = asort($array_only_odd_keys);
    for ($x = 0; $x <= count($array)/2; $x++) {
        if ($x & 1) {
            array_push($final_array, $array_only_odd_keys[$x],     $array_only_odd_stuff[$array_only_odd_keys[$x]]);
        }
        else {
            array_push($final_array, $array_only_even_keys[$x],     $array_only_odd_stuff[$array_only_even_keys[$x]]);
        }
    } 
    return $final_array;

This is how i'd do it in PHP though only if you want the final array to switch between even and odd keys like in your example.

Comments

0

The easiest way is probably to separate the array into even and odd arrays, sort the odd array, and then glue them back together:

$odd = $even = [];
foreach (array_chunk($myArray, 2, true) as $pair) {
    $odd += array_slice($pair, 0, 1, true);
    $even += array_slice($pair, 1, 1, true);
}

asort($odd);

$result = [];
for ($i = 0; $i < count($odd); $i++) {
    $result += array_slice($odd, $i, 1, true);
    $result += array_slice($even, $i, 1, true);
}

This rather naïve implementation assumes there is an equal number of odd and even numbers, they're always alternating and the array starts with an odd number.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.