ale
ale

Reputation: 11830

Swap the position of two associative array elements specified by their keys

I have an array:

$array = array(
    'a' => 'val1',
    'b' => 'val2',
    'c' => 'val3',
    'd' => 'val4'
);

How do I swap any two elements by their keys (e.g. a and d) to produce this array:

$array = array(
    'd' => 'val4',
    'b' => 'val2',
    'c' => 'val3',
    'a' => 'val1'
);

Upvotes: 6

Views: 9393

Answers (7)

Mostafa
Mostafa

Reputation: 1009

I have had the same problem for 2 months.. but in javascript ..after a lot of search and my old way that is incorrec unfortunately.(I find out) I update the answer here.( I tested it several times with different array size )

my old code:

$array = array('name' => 'mostafa', 'family' => 'mason', 'phone' => '524854745', 'sid' => '85487452660');
// Swap keys 'name' and 'sid'
list($array['name'], $array['sid']) = array($array['sid'], $array['name']);
// Swap keys 'family' and 'phone'
list($array['family'], $array['phone']) = array($array['phone'], $array['family']);
var_dump($array);

Update: I think there is some misunderstanding here myself.. yeah that's not the correct result by array_flip() as mentioned in the accepted answer. so here my update to one answer's but I think it's better we use $array[$key2] and $array[$key1] instead of just the $value1 or $value2 and also I add some array check.


function arr_change($array, $key1, $key2) {  
    if (array_key_exists($key1, $array) && array_key_exists($key2, $array)) {
        $myarr = [];
        foreach ($array as $key => $value) {
            if ($key === $key1) {
                $myarr[$key2] = $array[$key2];
            } elseif ($key === $key2) {
                $myarr[$key1] = $array[$key1];
            } else {
                $myarr[$key] = $value;
            }
        }
        return $myarr;
    }
    return $array;
}
$array = array('a' => 'val1', 'b' => 'val2', 'c' => 'val3', 'd' => 'val4');  
print_r($array);
$array = arr_change($array, 'a', 'd'); 
echo "<br/>";
print_r($array);

Upvotes: -1

mickmackusa
mickmackusa

Reputation: 47991

Declare the key swaps as a reflexive associative array. Then push the mapped data into the result array. If not found in the swapping array, transfer the elements directly to the result array while traversing the input array.

This process can accommodate multiple pairs of swaps or even chained swapping. Note that in the swapping array, the "values" are the keys of the elements to be moved and the "keys" are the destinations based on the original key's location. Demo

$array = ['a' => 'val1', 'b' => 'val2', 'c' => 'val3', 'd' => 'val4', 'e' => 'val5'];

$swaps = ['a' => 'd', 'd' => 'a'];

$result = [];
foreach ($array as $k => $v) {
    if (!isset($swaps[$k], $array[$swaps[$k]])) {
        $result[$k] = $v;
    } else {
        $result[$swaps[$k]] = $array[$swaps[$k]];
    }
}
var_export($result);

Output:

array (
  'd' => 'val4',
  'b' => 'val2',
  'c' => 'val3',
  'a' => 'val1',
  'e' => 'val5',
)

Extension:

$swaps = ['a' => 'd', 'd' => 'a', 'b' => 'e', 'e' => 'b']; makes:

array (
  'd' => 'val4',
  'e' => 'val5',
  'c' => 'val3',
  'a' => 'val1',
  'b' => 'val2',
)

$swaps = ['a' => 'c', 'c' => 'e', 'e' => 'a']; makes:

array (
  'c' => 'val3',
  'b' => 'val2',
  'e' => 'val5',
  'd' => 'val4',
  'a' => 'val1',
)

Upvotes: 0

Lexxx
Lexxx

Reputation: 33

I know this is quite old, but I needed this, and couldn't find anything satisfactory. So I rolled my own, and decided to share.

Using just one simple loop, this code is super readable to anyone.

I didn't benchmark, but I have a feeling it's not even that bad compared to the other array_keys, array_values, array_combine versions, even when going through a long array.

Should work for both numerical and string keys alike (only tested with string keys)

It's also easy to implement a check, if one or both keys not found and then throw error or return original array, or whatever you need

function arraySwap(array $array, $key1, $key2) {
    $value1 = $array[$key1];
    $value2 = $array[$key2];
    $newArray = [];
    foreach( $array as $key => $value ) {
        if ($key === $key1) {
            $newArray[$key2] = $value2;
        } else if ($key === $key2) {
            $newArray[$key1] = $value1;
        } else {
            $newArray[$key] = $value;
        }
    }

    return $newArray;
}

Upvotes: 0

Faraz
Faraz

Reputation: 761

You can use this function to swap any value in array to any key .

/**
* switch value with value on key in given array
* array_switch( array( a, b ,c), c,0 );
* will return array(c, b, a);
*
*
* @param array $array            
* @param mixed $value            
* @param mixed $key            
* @return array
*/
public static function array_switch(&$array, $value, $key)
{
   // find the key of current value
   $old_key = array_search($value, $array);
   // store value on current key in tmep
   $tmp = $array[$key];
   // set values
   $array[$key] = $value;
   $array[$old_key] = $tmp;       
   return $array;
}

Upvotes: 0

gen_Eric
gen_Eric

Reputation: 227290

Best A way is to make arrays of the keys and the values. Swap the positions in both arrays, and then put 'em back together.

function swapPos(&$arr, $pos1, $pos2){
  $keys = array_keys($arr);
  $vals = array_values($arr);
  $key1 = array_search($pos1, $keys);
  $key2 = array_search($pos2, $keys);

  $tmp = $keys[$key1];
  $keys[$key1] = $keys[$key2];
  $keys[$key2] = $tmp;

  $tmp = $vals[$key1];
  $vals[$key1] = $vals[$key2];
  $vals[$key2] = $tmp;

  $arr = array_combine($keys, $vals);
}

Demo: http://ideone.com/7gWKO

Upvotes: 2

No Results Found
No Results Found

Reputation: 102824

I thought there would be really simple answer by now, so I'll throw mine in the pile:

// Make sure the array pointer is at the beginning (just in case)
reset($array);

// Move the first element to the end, preserving the key
$array[key($array)] = array_shift($array);

// Go to the end
end($array);

// Go back one and get the key/value
$v = prev($array);
$k = key($array);

// Move the key/value to the first position (overwrites the existing index)
$array = array($k => $v) + $array;

This is swapping the first and last elements of the array, preserving keys. I thought you wanted array_flip() originally, so hopefully I've understood correctly.

Demo: http://codepad.org/eTok9WA6

Upvotes: 3

matino
matino

Reputation: 17725

Not ideal but does what you want to do:

$array = array('a' => 'val1', 'b' => 'val2', 'c' => 'val3', 'd' => 'val4');

$keys = array_keys($array);
swap($keys, 0, 3);
$values = array_values($array);
swap($values, 0, 3);
print_r(array_combine($keys, $values)); // Array ( [d] => val4 [b] => val2 [c] => val3 [a] => val1 )

function swap (&$arr, $e1, $e2)
{
    $temp = $arr[$e1];
    $arr[$e1] = $arr[$e2];
    $arr[$e2] = $temp;
}

Of course you should also check if both indexes are set in swap function (using isset)

Upvotes: 1

Related Questions