Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Associative array - change position

Tags:

php

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?

like image 518
ihtus Avatar asked Mar 01 '13 21:03

ihtus


3 Answers

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);
?>
like image 67
MIIB Avatar answered Oct 12 '22 23:10

MIIB


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
)
like image 35
ihtus Avatar answered Oct 13 '22 00:10

ihtus


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;
}
like image 42
Mike Starov Avatar answered Oct 12 '22 23:10

Mike Starov