Php如何交换两个关联数组的KEY?

3

我有以下输入:

array(
    'a' => 1,
    'b' => 2,
    'c' => 3,
    'd' => 4
);

我想获得这个:

array(
    'a' => 1,    
    'c' => 3,
    'b' => 2,
    'd' => 4
);

正如你所看到的,键变了,但它们的值没有变。我知道关联数组中没有固定的顺序 - 在我的情况下这很重要。那么,有什么解决办法吗?


1
你尝试过什么来达到你的目标吗? - Rizier123
3
是否有一种算法来确定顺序,还是只是对几个键定义的任意顺序? - Joaquín O
2
你使用了哪些规则将输入数组转换为输出数组所需的顺序?我假设你会告诉我们这些规则吗?我们没有必要自己推导出这些规则吧?只要告诉我们映射关系和排序顺序,那么我们很可能能够想出一个解决方案。 - Ryan Vincent
2
从 'e' 到 'h' 的下四个值是什么?提供的答案中哪些是正确的? - Ryan Vincent
2
有几个可能的系列 - 从有限的数据中,使用键:1)交替键序列,每隔2个键开始'a'然后'c'等。还有'b','d'。嗯...使用值也会得到这个序列。这是巧合吗? - Ryan Vincent
显示剩余3条评论
6个回答

6

另一种解决方案,适用于任意情况

$array = array(
    'a' => 1,
    'b' => 2,
    'c' => 3,
    'd' => 4
);

print_r($array);

$myNewOrder = ['a','c','d','b'];
$result = [];
foreach($myNewOrder as $key){
    $result[$key] = $array[$key];
}

$array = $result;

print_r($array);

输出:

Array
(
    [a] => 1
    [b] => 2
    [c] => 3
    [d] => 4
)
Array
(
    [a] => 1
    [c] => 3
    [d] => 4
    [b] => 2
)

1
一种可能的解决方案需要使用http://eosrei.net/articles/2011/11/php-arrayinsertafter-arrayinsertbefore中的array_insert_before函数(我不确定版权问题,因此不在此处复制其函数体)。
然后,您可以简单地声明另外两个函数:
function replaceKey(array &$arr, $keyFrom, $keyTo) {
    array_insert_before($keyFrom, $arr, $keyTo, $arr[$keyFrom]);
    unset($arr[$keyFrom]);
}

function swapKeys(array &$arr, $key1, $key2) {
    // $arr = array(x => a, y => b, z => c), $key1 = x, $key2 = z

    // generate a random value for "tmp" that is not a key of any element in $arr
    for($tmpName = 0; isset($arr[$tmpName]); $tmpName++);

    // array(tmp => a, y => b, z => c);
    replaceKey($arr, $key1, $tmpName);

    // array(tmp => a, y => b, x => c);
    replaceKey($arr, $key2, $key1);

    // array(z => a, y => b, x => c);
    replaceKey($arr, $tmpName, $key2);
}

没有保证,未经测试!这只是一个概念!

(保留HTML标记)

1

如评论所述,这是由您定义的任意顺序。因此,这里提供了一种简单(但不可扩展)的方法,使用辅助数组。

<?php
    $start = array(
        "a" => 1,
        "b" => 2,
        "c" => 3,
        "d" => 4
    );

    $aux = array(
        "a" => $start["a"],
        "c" => $start["b"],
        "b" => $start["c"],
        "d" => $start["d"],
    );

    $start = $aux;
    var_dump($start);
    die();
?>

这是一种更具可扩展性和编程化的方法。我使用了一个辅助数组和一个翻译数组。
<?php
    $start = array(
        "a" => 1,
        "b" => 2,
        "c" => 3,
        "d" => 4
    );

    $translate = array(
        "a" => "a",
        "b" => "c",
        "c" => "b",
        "d" => "d"
    );

    $aux = array();

    foreach($translate as $old => $new) {
        $aux[$new] = $start[$old];
    }

    $start = $aux;
    var_dump($start);
    die();
?>

1
我并不为这段代码感到自豪,但你必须接受你有一个奇怪的需求。 - Joaquín O

1
[编辑] 新答案 - 如果是任意定义,先奇数后偶数。
$b=array_flip($array);
foreach ($b as $k => $v) {
    ($k % 2 == 0)?$even[$k]=$v:$odd[$k]=$v;
}
$n=$odd+$even;
$n=array_flip($n);
//print_r($n);

最短、最简洁的(之前 - 如果没有定义)
$b=array_flip($array);
shuffle($b);
$new=array_flip($b);
//print_r($new);

2
OP 要求任意定义的顺序。这是未定义的顺序。 - Joaquín O
1
是偶数还是奇数?:/ 这不是很清楚。我有点困惑。一开始是随机的,现在变成了偶数和奇数。其中一个应该是正确的。请帮我澄清一下 :) - aimme
1
OP想要定义一个任意顺序。不是随机的,不是“大于”,甚至不是奇偶数,也不是任何逻辑规则。这是我从他的问题中理解到的。如果我错了,请原谅。 - Joaquín O
1
@JoaquínO 什么事情都不是自动发生的,所以告诉我我们如何在没有算法的情况下进行计算:/ 。现在我更加困惑了,我的第一个答案是如此随意,以至于任何人都无法猜测。 - aimme
1
我们根据提问者的说法来提供答案 :) - aimme
显示剩余2条评论

1
我相信这是您所需的功能。
function shuffle_assoc($array) {

    $keys = array_keys($array);
    shuffle($keys);

    foreach($keys as $key) {
        $new[$key] = $array[$key];
    }

    $array = $new;    
    return $array;
}

如果OP想要提供一个特定的顺序:
function shuffle_assoc_by_order($array, $order) {

    foreach($order as $key) {
        $new[$key] = $array[$key];
    }

    $array = $new;    
    return $array;
}

使用方法: shuffle_assoc_by_order($input, ['a', 'c', 'b', 'd']);


1
OP 要求任意定义的顺序。这是未定义的顺序。 - Joaquín O
1
@JoaquínO 所以 OP 会提供某种输入来排序吗?我认为 OP 没有澄清问题。 - thecodeparadox

0

感谢所有的答案,这并不像我想象的那么容易。我为此编写了一个通用函数:

/**
 * @return array
 */
public final static function swapAssociativeKeys (array &$array, $key1, $key2)
{
    for ($i = 0; $i < sizeof($array); $i++)
    {
        if (array_keys($array)[$i] == $key1)
        {
            $key1at = $i;
        }
        if (array_keys($array)[$i] == $key2)
        {
            $key2at = $i;
        }
    }
    if ($key1at > $key2at)
    {
        $i = $key1at;
        $key1at = $key2at;
        $key2at = $i;
    }

    $order = array();
    for ($i = 0; $i < sizeof($array); $i++)
    {
        if ($i == $key1at)
        {
            $order[] = array_keys($array)[$key2at];
        }
        else
        {
            if ($i == $key2at)
            {
                $order[] = array_keys($array)[$key1at];
            }
            else
            {
                $order[] = array_keys($array)[$i];
            }
        }
    }

    $return = array();
    foreach ($order as $i)
    {
        $return[$i] = $array[$i];
    }
    return $return;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接