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
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
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 );
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).
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
)
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.
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.