在关联数组中切换两个元素

例子:


$arr = array/
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
/;


我想切换葡萄柚的位置 pear, 这样阵列是


$arr = array/
'apple' => 'sweet',
'pear' => 'tasty',
'grapefruit' => 'bitter',
'banana' => 'yellow'
/


我知道我想要切换的物品的键和价值,有一种简单的方法吗? 或者这需要一个周期。 + 创建一个新数组?

已邀请:

八刀丁二

赞同来自:

比解决方案略微较短,困难 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/;
?>


验证并工作正常

小明明

赞同来自:

这是我的交换功能版本:


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/;
}

三叔

赞同来自:

如果阵列来自数据库,则添加一个字段 sort_order, 始终自信,在阵列中的订单中。

快网

赞同来自:

它不确定是提到的,但原因是难的原因是它没有索引。

让我们来:


$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 在 'order' 重新排列的钥匙。


$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;
}
}
?>


WARNING: 请在使用之前测试和调试它 - 根本没有测试。

江南孤鹜

赞同来自:

根据您的特定使用选项,这可能是或不成为选项,但如果初始化您的数组值 null 在填写其数据之前,使用适当的键,您可以按任何顺序设置值,并且将保存键的源键。 因此,而不是更换项目,您可以防止需要完全替换它们:


$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
/

知食

赞同来自:

没有简单的方法,只是循环或数组的新定义。

君笑尘

赞同来自:

经典关联阵列未定义并且不保证元素序列。 为此,有一个简单的数组/向量。 如果您使用的是关联数组,则假设您需要随机访问,但不一致。 对我来说,你使用数组 assoc 对于未创建的任务。

喜特乐

赞同来自:

是的,我同意Lex如果使用关联数组来存储数据,为什么不使用您的逻辑处理如何处理它们,而不是根据它们在数组中的位置。

如果您真的想确保它们是正确的顺序,请尝试创建水果对象,然后将它们放在常规阵列中。

卫东

赞同来自:

没有简单的方法来做。 这听起来像你的小逻辑错误,它导致你试图在有更好的方法做你想做的事情时做到这一点。 你能告诉我们你为什么要这样做吗?

你这么说
I know the keys and values of the elements I want to switch

, 是什么让我觉得你真正想要的 - 这是一种排序功能,因为您可以在您想要的任何时间轻松访问所需的项目。


$value = $array[$key];


如果是这样,我会使用
http://us.php.net/manual/en/function.sort.php
,
http://us.php.net/manual/en/function.ksort.php
或许多其他排序函数中的一种,以获取您想要的数组。 你甚至可以使用 usort//
http://us.php.net/manual/en/function.usort.php
Sort an array by values using a user-defined comparison function

.

另外,你可以使用
http://us.php.net/manual/en/fu ... e.php
, 如果您需要更改值或键。

知食

赞同来自:

这是两个解决方案。 第一个更长,但不创建一个临时数组,所以它可以节省内存。 第二个可能更快地工作,但使用更多内存:


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;
}

冰洋

赞同来自:

有一种简单的方法:


$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'
/

小明明

赞同来自:

fwiw 以下是用于更换两个相邻物品以实现实现功能 moveUp// 或者 moveDown// 在一个没有的关联阵列中 foreach//


/**
* @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//;
}

小明明

赞同来自:

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;
}

诸葛浮云

赞同来自:

我还将分享我的简短版本,它既用数字和关联阵列工作。


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'/;

涵秋

赞同来自:

好吧,这只是一个问题排序键。 为此,我们可以使用
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/;

喜特乐

赞同来自:

我写了一个更通用的目的,这意味着这个问题。

数组与着名钥匙

在第二个阵列中指定键的顺序 /$订单数组的键表示关键位置/

功能 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 /


我希望它是相关的 / 对某人有用

卫东

赞同来自:

PHP中的数组是有序地图。


$arr = array/'apple'=>'sweet','grapefruit'=>'bitter','
pear'=>'tasty','banana'=>'yellow'/;


这并不意味着第一元素是相等的 'apple'=>'sweet', 最后一个 - 'banana'=>'yellow' 只是因为你放了 'apple' 首先,我。 'banana' 最新的。 实际上, 'apple'=>'sweet' 将是第一个I.
'banana'=>'yellow' 由于排序升序的字母顺序将是第二个。

要回复问题请先登录注册