Reputation: 11830
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
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
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
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
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
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
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
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