Reputation: 2811
For ex have this array:
[food] => Array (
[fruits] => apple
[vegetables] => garlic
[nuts] => cashew
[meat] => beaf
)
I need to change the position of a specific key-value combination.
Let's say I need to move [fruits] => apple to 3rd position
[food] => Array (
[vegetables] => garlic
[nuts] => cashew
[fruits] => apple
[meat] => beaf
)
I am not talking about sorting by key or value. I need to change position of key-value to a very strict new position.
Something like:
change_pos($my_arr, $key_to_move, $new_index);
=>
change_pos($my_arr, "fruits", 3);
Is that possible?
Upvotes: 6
Views: 11871
Reputation: 1
/**
* Moves an array item to a new index .
*
* @param array $array
* @param int $from
* @param int $to
* @return void
*/
function array_move(array &$array, int $from, int $to)
{
$item = array_splice($array, $from, 1);
array_splice($array, $to, 0, $item);
}
/**
* Moves an associative array item to a new index.
*
* @param array $array
* @param string $key
* @param int $to
* @return void
*/
function array_move_assoc(array &$array, string $key, int $to)
{
if (!array_key_exists($key, $array)) return;
$keys = array_keys($array);
$values = array_values($array);
$from = array_search($key, $keys);
array_move($keys, $from, $to);
array_move($values, $from, $to);
$array = [];
foreach ($keys as $index => $key) {
$array[$key] = $values[$index];
}
}
$array = [
"fruits" => "apple",
"vegetables" => "garlic",
"nuts" => "cashew",
"meat" => "beaf"
];
array_move_assoc($array, "fruits", 2);
print_r($array);
Array
(
[vegetables] => garlic
[nuts] => cashew
[fruits] => apple
[meat] => beaf
)
Upvotes: 0
Reputation: 2811
I would like to thank MIIB for his hard work! I will accept his answer for the hard work.
But I came up with a solution that fits me better and I will use it.
function ksort_arr (&$arr, $index_arr) {
$arr_t=array();
foreach($index_arr as $i=>$v) {
foreach($arr as $k=>$b) {
if ($k==$v) $arr_t[$k]=$b;
}
}
$arr=$arr_t;
}
$arr=array("fruits"=>"apple","vegetables"=>"garlic","nuts"=>"cashew","meat"=>"beaf");
$index_arr=array("vegetables","meat","fruits","nuts");
ksort_arr($arr,$index_arr);
print_r($arr);
result
Array
(
[vegetables] => garlic
[meat] => beaf
[fruits] => apple
[nuts] => cashew
)
Upvotes: 3
Reputation: 7296
Here is a much simpler solution using a second array. It also provides some basic validation for new index parameter. Intended to be used with associative arrays only. It does not make sense to be used with numeric arrays.
function array_move($key, $new_index, $array)
{
if($new_index < 0) return;
if($new_index >= count($array)) return;
if(!array_key_exists($key, $array)) return;
$ret = array();
$ind = 0;
foreach($array as $k => $v)
{
if($new_index == $ind)
{
$ret[$key] = $array[$key];
$ind++;
}
if($k != $key)
{
$ret[$k] = $v;
$ind++;
}
}
// one last check for end indexes
if($new_index == $ind)
$ret[$key] = $array[$key];
return $ret;
}
Upvotes: 2
Reputation: 1849
It was hard , but finally:
<?php
function array_splice_assoc(&$input, $offset, $length, $replacement) {
$replacement = (array) $replacement;
$key_indices = array_flip(array_keys($input));
if (isset($input[$offset]) && is_string($offset)) {
$offset = $key_indices[$offset];
}
if (isset($input[$length]) && is_string($length)) {
$length = $key_indices[$length] - $offset;
}
$input = array_slice($input, 0, $offset, TRUE)
+ $replacement
+ array_slice($input, $offset + $length, NULL, TRUE);
}
function array_move($which, $where, $array)
{
$tmpWhich = $which;
$j=0;
$keys = array_keys($array);
for($i=0;$i<count($array);$i++)
{
if($keys[$i]==$tmpWhich)
$tmpWhich = $j;
else
$j++;
}
$tmp = array_splice($array, $tmpWhich, 1);
array_splice_assoc($array, $where, 0, $tmp);
return $array;
}
$array = array('fruits' => 'apple','vegetables' => 'garlic','nuts' => 'cashew','meat' => 'beaf');
$res = array_move('vegetables',2,$array);
var_dump($res);
?>
Upvotes: 7