Your method custom sorts the array while maintaining all associative relationships.
To demonstrate with some data:
$array=['a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5];
var_export(array_swap_assoc('b','d',$array));
Output:
array (
'a' => 1,
'd' => 4,
'c' => 3,
'b' => 2,
'e' => 5,
)
Félix Gagnon-Grenier's method does not provide the same effect and the function would be better named swap_values_by_key()
. Notice the difference in output, only the values are re-ordered while the keys stay the same. This yields a set of dissociated elements.
array (
'a' => 1,
'b' => 4,
'c' => 3,
'd' => 2,
'e' => 5,
)
If this is the result that you desire, (skipping the check for key existence) it can be achieved with a single temporary variable.
function simple_value_swap($key1,$key2,$array){
$tmp=$array[$key1];
$array[$key1]=$array[$key2];
$array[$key2]=$tmp;
return $array;
}
All that said, Félix's recommendation about checking for keys is advisable to avoid receiving a Notice about trying to access an element by a non-existent key.
I am certainly not against modifying variables by reference, but some developers discourage it.
If you are handling small arrays, then your posted method that iterates the entire array will not cause any noticeable impact on performance.
If you are handling a much larger array, and cannot sort the data more eloquently during an earlier process in your code, then you may or may not receive improved performance (I didn't do any benchmarking) with this:
function swap_assoc_offsets($key1,$key2,$array){
$keys=array_keys($array);
if(($offset1=array_search($key1,$keys))!==false && ($offset2=array_search($key2,$keys))!==false){
$tmp=$keys[$offset1];
$keys[$offset1]=$keys[$offset2];
$keys[$offset2]=$tmp;
return array_merge(array_flip($keys),$array);
}
}
...p.s. Just for the sake of trying, here is a less eloquent method: (Demo)
function repack_slices($key1,$key2,$array){
$keys=array_keys($array);
if(($offset1=array_search($key1,$keys))!==false && ($offset2=array_search($key2,$keys))!==false){
$max=max($offset1,$offset2);
$min=min($offset1,$offset2);
$result=array_slice($array,0,$min,true); // front elements (possibly empty)
$result+=array_slice($array,$max,1,true); // the max/later element
$result+=array_slice($array,$min+1,$max-1-$min,true); // middle elements (possibly empty)
$result+=array_slice($array,$min,1,true); // the min/earlier element
$result+=array_slice($array,++$max,sizeof($array)-$max,true); // back elements (possibly empty)
return $result;
}
}