如何在PHP中反转多维数组

时间:2010-02-18 21:31:42

标签: php arrays

什么是反转多维数组的最简单方法。通过反转我的意思类似于array_flip。

e.g

[0][5][var_name] = data
[0][3][var_name2] = data2
[1][var_name3] = data3
[0][1][4][var_name4] = data4

倒置将是:

[var_name][0][5] = data
[var_name2][0][3] = data2
[var_name3][1] = data3
[var_name4][0][1][4] = data4

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我想不出一个简单的方法来做到这一点。所以我写了一个非常复杂的方法来做到这一点。即:

  1. 获取多维数组并将其展平为键和值列表。
  2. 反转键。
  3. 取消列表以获取倒置的多维数组。
  4. 代码

    <?php
    function print_entries($array, $prekeys = array())
    {
        foreach ($array as $key => $value)
        {
            $keys = array_merge($prekeys, array($key));
    
            if (is_array($value))
                print_entries($value, $keys);
            else
                echo '[' . implode('][', $keys) . "] = $value\n";
        }
    }
    
    function flatten_array($array)
    {
        $entries = array();
    
        foreach ($array as $key => $value)
        {
            if (is_array($value))
            {
                foreach (flatten_array($value) as $subentry)
                {
                    $subkeys  = $subentry[0];
                    $subvalue = $subentry[1];
    
                    $entries[] = array(array_merge(array($key), $subkeys), $subvalue);
                }
            }
            else
                $entries[] = array(array($key), $value);
        }
    
        return $entries;
    }
    
    function unflatten_array($entries)
    {
        $array = array();
    
        foreach ($entries as $entry)
        {
            $keys  = $entry[0];
            $value = $entry[1];
    
            $subarray = &$array;
    
            foreach ($keys as $i => $key)
            {
                if ($i < count($keys) - 1)
                {
                    if (!isset($subarray[$key]))
                        $subarray[$key] = array();
    
                    $subarray = &$subarray[$key];
                }
                else
                    $subarray[$key] = $value;
            }
        }
    
        return $array;
    }
    
    function invert_array($array)
    {
        $entries = flatten_array($array);
    
        foreach ($entries as &$entry)
            $entry[0] = array_reverse($entry[0]);
    
        return unflatten_array($entries);
    }
    
    $array = array
    (
        0 => array
        (
            5 => array('var_name' => 'data'),
            3 => array('var_name2' => 'data2'),
            1 => array(4 => array('var_name4' => 'data4'))
        ),
    
        1 => array(0 => array('var_name' => 'data3'))
    );
    
    print_entries($array);
    echo "\n";
    print_entries(invert_array($array));
    ?>
    

    输出

    [0][5][var_name] = data
    [0][3][var_name2] = data2
    [0][1][4][var_name4] = data4
    [1][0][var_name] = data3
    
    [var_name][5][0] = data
    [var_name2][3][0] = data2
    [var_name4][4][1][0] = data4
    [var_name][0][1] = data3
    

    编辑:我现在注意到你没有反转键,只是简单地将var_name部分从末尾移到前面并保留数字索引。修改flatten_array中的行很容易,我调用array_reverse以不同的方式重新排序键。核心展平/不平坦逻辑不需要改变。我将此作为练习留给读者。 : - )

答案 1 :(得分:1)

您可以存储所有祖先的键列表,当您点击“叶子”时,使用此列表创建“翻转”版本。

<?php
$data = array(
  0=>array(
    5=>array('var_name' => 'data'),
    3=>array('var_name2' => 'data2'),
    1=>array(4=>array('var_name4'=>'data4'))
  ),
  1=>array('var_name3'=>'data3')
);

$result = array();
foo($data, $result);

($result['var_name'][0][5] === 'data') or die('1');
($result['var_name2'][0][3] === 'data2') or die('2');
($result['var_name3'][1] === 'data3') or die('3');
($result['var_name4'][0][1][4] === 'data4') or die('4');
echo 'ok';


function foo(array $a, array &$target, $stack=array()) {
  foreach($a as $key=>$value) {
    if ( is_array($value) ) {
      array_push($stack, $key);
      foo($value, $target, $stack);
      array_pop($stack);
    }
    else {
      $target[$key] = array();
      $tmp = &$target[$key];
      foreach( $stack as $s ) { // now it's not so stack-ish anymore :-S
        $tmp[$s] = array();
        $tmp = &$tmp[$s];
      }
      $tmp = $value;
    }
  }
}