示例:
$arr = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
我想切换葡萄柚和梨的位置,所以阵列将成为
$arr = array(
'apple' => 'sweet',
'pear' => 'tasty',
'grapefruit' => 'bitter',
'banana' => 'yellow'
)
我知道要切换的元素的键和值,是否有一种简单的方法可以做到这一点?或者它需要一个循环+创建一个新数组?
由于
答案 0 :(得分:18)
比arcaneerudite的解决方案更短,更简单:
<?php
if(!function_exists('array_swap_assoc')) {
function array_swap_assoc($key1, $key2, $array) {
$newArray = array ();
foreach ($array as $key => $value) {
if ($key == $key1) {
$newArray[$key2] = $array[$key2];
} elseif ($key == $key2) {
$newArray[$key1] = $array[$key1];
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}
}
$array = $arrOrig = array(
'fruit' => 'pear',
'veg' => 'cucumber',
'tuber' => 'potato',
'meat' => 'ham'
);
$newArray = array_swap_assoc('veg', 'tuber', $array);
var_dump($array, $newArray);
?>
经过测试并且工作正常
答案 1 :(得分:4)
这是我的交换功能版本:
function array_swap_assoc(&$array,$k1,$k2) {
if($k1 === $k2) return; // Nothing to do
$keys = array_keys($array);
$p1 = array_search($k1, $keys);
if($p1 === FALSE) return; // Sanity check...keys must exist
$p2 = array_search($k2, $keys);
if($p2 === FALSE) return;
$keys[$p1] = $k2; // Swap the keys
$keys[$p2] = $k1;
$values = array_values($array);
// Swap the values
list($values[$p1],$values[$p2]) = array($values[$p2],$values[$p1]);
$array = array_combine($keys, $values);
}
答案 2 :(得分:2)
如果数组来自db,请添加sort_order字段,以便始终确保元素在数组中的顺序。
答案 3 :(得分:1)
这可能是也可能不是一个选项,具体取决于您的特定用例,但如果使用适当的键在使用数据填充数据之前使用空值初始化数组,则可以按任何顺序设置值和原始键订单将被维护。因此,您可以避免交换元素,而不是交换元素:
$arr = array('apple' => null,
'pear' => null,
'grapefruit' => null,
'banana' => null);
...
$arr['apple'] = 'sweet';
$arr['grapefruit'] = 'bitter'; // set grapefruit before setting pear
$arr['pear'] = 'tasty';
$arr['banana'] = 'yellow';
print_r($arr);
>>> Array
(
[apple] => sweet
[pear] => tasty
[grapefruit] => bitter
[banana] => yellow
)
答案 4 :(得分:1)
不完全确定是否提到了这一点,但是,这很棘手的原因是因为它没有索引。
我们来看看:
$arrOrig = array(
'fruit'=>'pear',
'veg'=>'cucumber',
'tuber'=>'potato'
);
获取钥匙:
$arrKeys = array_keys($arrOrig);
print_r($arrKeys);
Array(
[0]=>fruit
[1]=>veg
[2]=>tuber
)
获取值:
$arrVals = array_values($arrOrig);
print_r($arrVals);
Array(
[0]=>pear
[1]=>cucumber
[2]=>potato
)
现在你有2个数字数组。交换要交换的索引,然后按修改后的数值数组的顺序读回另一个数组。假设我们要交换'fruit'和'veg':
$arrKeysFlipped = array_flip($arrKeys);
print_r($arrKeysFlipped);
Array (
[fruit]=>0
[veg]=>1
[tuber]=>2
)
$indexFruit = $arrKeysFlipped['fruit'];
$indexVeg = $arrKeysFlipped['veg'];
$arrKeysFlipped['veg'] = $indexFruit;
$arrKeysFlipped['fruit'] = $indexVeg;
print_r($arrKeysFlipped);
Array (
[fruit]=>1
[veg]=>0
[tuber]=>2
)
现在,你可以换回数组:
$arrKeys = array_flip($arrKeysFlipped);
print_r($arrKeys);
Array (
[0]=>veg
[1]=>fruit
[2]=>tuber
)
现在,您可以通过重新排列键的“顺序”中的oringal数组来构建数组。
$arrNew = array ();
foreach($arrKeys as $index=>$key) {
$arrNew[$key] = $arrOrig[$key];
}
print_r($arrNew);
Array (
[veg]=>cucumber
[fruit]=>pear
[tuber]=>potato
)
我没有测试过这个 - 但这是我所期待的。这至少提供了什么样的帮助吗?祝你好运:)
您可以将其放入函数$arrNew = array_swap_assoc($key1,$key2,$arrOld);
<?php
if(!function_exists('array_swap_assoc')) {
function array_swap_assoc($key1='',$key2='',$arrOld=array()) {
$arrNew = array ();
if(is_array($arrOld) && count($arrOld) > 0) {
$arrKeys = array_keys($arrOld);
$arrFlip = array_flip($arrKeys);
$indexA = $arrFlip[$key1];
$indexB = $arrFlip[$key2];
$arrFlip[$key1]=$indexB;
$arrFlip[$key2]=$indexA;
$arrKeys = array_flip($arrFlip);
foreach($arrKeys as $index=>$key) {
$arrNew[$key] = $arrOld[$key];
}
} else {
$arrNew = $arrOld;
}
return $arrNew;
}
}
?>
警告:请在使用之前对其进行测试和调试 - 根本没有进行任何测试。
答案 5 :(得分:0)
嗯,这只是一个关键的排序问题。为此,我们可以使用uksort
。它需要一个键比较功能,我们只需要知道应该返回0即可保持键位置不变,而返回0则可以返回上下键。
请注意,仅当您要交换的密钥彼此相邻时,此方法才有效。
<?php
$arr = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
uksort(
$arr,
function ($k1, $k2) {
if ($k1 == 'grapefruit' && $k2 == 'pear') return 1;
else return 0;
}
);
var_dump($arr);
答案 6 :(得分:0)
没有简单的方法,只是循环或新的数组定义。
答案 7 :(得分:0)
我也将分享我的简短版本,它适用于数字数组和关联数组。
array array_swap ( array $array , mixed $key1 , mixed $key2 [, bool $preserve_keys = FALSE [, bool $strict = FALSE ]] )
返回交换了两个元素的新数组。如果指定,它将保留原始密钥。如果找不到密钥,则返回FALSE。
function array_swap(array $array, $key1, $key2, $preserve_keys = false, $strict = false) {
$keys = array_keys($array);
if(!array_key_exists($key1, $array) || !array_key_exists($key2, $array)) return false;
if(($index1 = array_search($key1, $keys, $strict)) === false) return false;
if(($index2 = array_search($key2, $keys, $strict)) === false) return false;
if(!$preserve_keys) list($keys[$index1], $keys[$index2]) = array($key2, $key1);
list($array[$key1], $array[$key2]) = array($array[$key2], $array[$key1]);
return array_combine($keys, array_values($array));
}
例如:
$arr = array_swap($arr, 'grapefruit', 'pear');
答案 8 :(得分:0)
function arr_swap_keys(array &$arr, $key1, $key2, $f_swap_vals=false) {
// if f_swap_vals is false, then
// swap only the keys, keeping the original values in their original place
// ( i.e. do not preserve the key value correspondence )
// i.e. if arr is (originally)
// [ 'dog' => 'alpha', 'cat' => 'beta', 'horse' => 'gamma' ]
// then calling this on arr with, e.g. key1 = 'cat', and key2 = 'horse'
// will result in arr becoming:
// [ 'dog' => 'alpha', 'horse' => 'beta', 'cat' => 'gamma' ]
//
// if f_swap_vals is true, then preserve the key value correspondence
// i.e. in the above example, arr will become:
// [ 'dog' => 'alpha', 'horse' => 'gamma', 'cat' => 'beta' ]
//
//
$arr_vals = array_values($arr); // is a (numerical) index to value mapping
$arr_keys = array_keys($arr); // is a (numerical) index to key mapping
$arr_key2idx = array_flip($arr_keys);
$idx1 = $arr_key2idx[$key1];
$idx2 = $arr_key2idx[$key2];
swap($arr_keys[$idx1], $arr_keys[$idx2]);
if ( $f_swap_vals ) {
swap($arr_vals[$idx1], $arr_vals[$idx2]);
}
$arr = array_combine($arr_keys, $arr_vals);
}
function swap(&$a, &$b) {
$t = $a;
$a = $b;
$b = $t;
}
答案 9 :(得分:0)
有一种简单的方法:
$sourceArray = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
// set new order
$orderArray = array(
'apple' => '', //this values would be replaced
'pear' => '',
'grapefruit' => '',
//it is not necessary to touch all elemets that will remains the same
);
$result = array_replace($orderArray, $sourceArray);
print_r($result);
你得到:
$result = array(
'apple' => 'sweet',
'pear' => 'tasty',
'grapefruit' => 'bitter',
'banana' => 'yellow'
)
答案 10 :(得分:0)
fwiw这是一个交换两个相邻项的函数,用于在没有foreach()的关联数组中实现moveUp()或moveDown()
/**
* @param array $array to modify
* @param string $key key to move
* @param int $direction +1 for down | -1 for up
* @return $array
*/
protected function moveInArray($array, $key, $direction = 1)
{
if (empty($array)) {
return $array;
}
$keys = array_keys($array);
$index = array_search($key, $keys);
if ($index === false) {
return $array; // not found
}
if ($direction < 0) {
$index--;
}
if ($index < 0 || $index >= count($array) - 1) {
return $array; // at the edge: cannot move
}
$a = $keys[$index];
$b = $keys[$index + 1];
$result = array_slice($array, 0, $index, true);
$result[$b] = $array[$b];
$result[$a] = $array[$a];
return array_merge($result, array_slice($array, $index + 2, null, true));
}
答案 11 :(得分:0)
这是两个解决方案。第一个是更长的,但不创建临时数组,因此它节省了内存。第二个可能运行得更快,但使用更多内存:
function swap1(array &$a, $key1, $key2)
{
if (!array_key_exists($key1, $a) || !array_key_exists($key2, $a) || $key1 == $key2) return false;
$after = array();
while (list($key, $val) = each($a))
{
if ($key1 == $key)
{
break;
}
else if ($key2 == $key)
{
$tmp = $key1;
$key1 = $key2;
$key2 = $tmp;
break;
}
}
$val1 = $a[$key1];
$val2 = $a[$key2];
while (list($key, $val) = each($a))
{
if ($key == $key2)
$after[$key1] = $val1;
else
$after[$key] = $val;
unset($a[$key]);
}
unset($a[$key1]);
$a[$key2] = $val2;
while (list($key, $val) = each($after))
{
$a[$key] = $val;
unset($after[$key]);
}
return true;
}
function swap2(array &$a, $key1, $key2)
{
if (!array_key_exists($key1, $a) || !array_key_exists($key2, $a) || $key1 == $key2) return false;
$swapped = array();
foreach ($a as $key => $val)
{
if ($key == $key1)
$swapped[$key2] = $a[$key2];
else if ($key == $key2)
$swapped[$key1] = $a[$key1];
else
$swapped[$key] = $val;
}
$a = $swapped;
return true;
}
答案 12 :(得分:0)
没有简单的方法可以做到这一点。这听起来像是一个轻微的设计逻辑错误,当你有更好的方法去做你想做的事情时,这会导致你尝试这样做。你能告诉我们你为什么要这样做吗?
你说I know the keys and values of the elements I want to switch
让我觉得你真正想要的是一个排序功能,因为你可以随时随地轻松访问适当的元素。
$value = $array[$key];
如果是这种情况,那么我会使用sort(),ksort()或许多其他排序函数之一来获得您想要的数组。您甚至可以usort()使用Sort an array by values using a user-defined comparison function
。
除此之外,如果您需要交换值或键,则可以使用array_replace()。
答案 13 :(得分:0)
是的我同意Lex,如果你使用关联数组来保存数据,为什么不使用你的逻辑句柄来访问它们,而不是取决于它们在数组中的排列方式。
如果您真的想确保它们的顺序正确,请尝试创建水果对象,然后将它们放入正常的数组中。
答案 14 :(得分:0)
经典关联数组不以任何方式定义或保证元素序列。有平原数组/向量。如果使用关联数组,则假定您需要随机访问但不需要顺序访问。对我来说,你正在使用assoc数组来完成它的任务。
答案 15 :(得分:-1)
我写了一个更通用的函数,记住了这个问题。
function order_array($ array,$ order){
foreach (array_keys($array) as $k => $v) {
$keys[++$k] = $v;
}
for ($i = 1; $i <= count($array); $i++) {
if (isset($order[$i])) {
unset($keys[array_search($order[$i], $keys)]);
}
if ($i === count($array)) {
array_push($keys, $order[$i]);
} else {
array_splice($keys, $i-1, 0, $order[$i]);
}
}
}
foreach ($keys as $key) {
$result[$key] = $array[$key];
}
return $result;
} else {
return false;
}
}
$order = array(1 => 'item3', 2 => 'item5');
$array = array("item1" => 'val1', "item2" => 'val2', "item3" => 'val3', "item4" => 'val4', "item5" => 'val5');
print_r($array); -> Array ( [item1] => val1 [item2] => val2 [item3] => val3 [item4] => val4 [item5] => val5 )
print_r(order_array($array, $order)); -> Array ( [item3] => val3 [item5] => val5 [item1] => val1 [item2] => val2 [item4] => val4 )
我希望这对某人有用/有用
答案 16 :(得分:-2)
php中的数组是有序地图。
$arr = array('apple'=>'sweet','grapefruit'=>'bitter','
pear'=>'tasty','banana'=>'yellow');
并不意味着第一个元素是'apple'=&gt;'sweet'而最后一个 - 'banana'=&gt;'yellow'只是因为你先把'apple'和'banana'放在最后。实际上,'apple'=&gt;'sweet'将是第一个和 'banana'=&gt;'yellow'将是第二个,因为按字母顺序升序排序。