복붙노트

PHP로 다차원 배열 변환하기

PHP

PHP로 다차원 배열 변환하기

PHP에서 다차원 배열을 어떻게 90도 바꿀 수 있습니까? 예 :

// Start with this array
$foo = array(
    'a' => array(
       1 => 'a1',
       2 => 'a2',
       3 => 'a3' 
    ),
    'b' => array(
       1 => 'b1',
       2 => 'b2',
       3 => 'b3' 
    ),
    'c' => array(
       1 => 'c1',
       2 => 'c2',
       3 => 'c3' 
    )
);

$bar = flipDiagonally($foo); // Mystery function
var_dump($bar[2]);

// Desired output:
array(3) {
  ["a"]=>
  string(2) "a2"
  ["b"]=>
  string(2) "b2"
  ["c"]=>
  string(2) "c2"
}

어떻게 flipDiagonally ()를 구현하겠습니까?

편집 : 이것은 숙제가 아닙니다. 난 단지 어떤 SOers가 가장 명백한 경로보다 더 창의적인 솔루션을 가지고 있는지보고 싶습니다. 하지만 몇 사람이이 문제에 대해 너무 쉽게 불평을하기 때문에 n 번째 차원 배열과 함께 작동하는 좀 더 일반적인 해결책은 무엇입니까?

ie : 어떻게 함수를 작성하여 다음을 할 수 있을까요?

$foo[j][k][...][x][y][z] = $bar[z][k][...][x][y][j]

? (추신 : 12 중첩 된 루프가이 경우 최상의 솔루션이라고 생각하지 않습니다.)

해결법

  1. ==============================

    1.

    function transpose($array) {
        array_unshift($array, null);
        return call_user_func_array('array_map', $array);
    }
    

    또는 PHP 5.6 이상을 사용하는 경우 :

    function transpose($array) {
        return array_map(null, ...$array);
    }
    
  2. ==============================

    2.

    2 개의 루프.

    function flipDiagonally($arr) {
        $out = array();
        foreach ($arr as $key => $subarr) {
            foreach ($subarr as $subkey => $subvalue) {
                $out[$subkey][$key] = $subvalue;
            }
        }
        return $out;
    }
    
  3. ==============================

    3.

    배열 전치 (열이 행이되고 행이 열이됩니다)를 참조한다고 생각합니다.

    다음은 소스 (source)를위한 함수입니다.

    function array_transpose($array, $selectKey = false) {
        if (!is_array($array)) return false;
        $return = array();
        foreach($array as $key => $value) {
            if (!is_array($value)) return $array;
            if ($selectKey) {
                if (isset($value[$selectKey])) $return[] = $value[$selectKey];
            } else {
                foreach ($value as $key2 => $value2) {
                    $return[$key2][$key] = $value2;
                }
            }
        }
        return $return;
    } 
    
  4. ==============================

    4.

    N 차원 배열 전치 :

    function transpose($array, &$out, $indices = array())
    {
        if (is_array($array))
        {
            foreach ($array as $key => $val)
            {
                //push onto the stack of indices
                $temp = $indices;
                $temp[] = $key;
                transpose($val, $out, $temp);
            }
        }
        else
        {
            //go through the stack in reverse - make the new array
            $ref = &$out;
            foreach (array_reverse($indices) as $idx)
                $ref = &$ref[$idx];
            $ref = $array;
        }
    }
    
    $foo[1][2][3][3][3] = 'a';
    $foo[4][5][6][5][5] = 'b';
    
    $out = array();
    transpose($foo, $out);
    
    echo $out[3][3][3][2][1] . ' ' . $out[5][5][6][5][4];
    

    진짜로 hackish, 아마 아닙니다 제일 해결책, 그러나 어이 그것은 작동한다.

    기본적으로 배열을 재귀 적으로 가로 지르며 배열에 현재 인디케이터를 누적합니다. 일단 참조 된 값에 도달하면 인덱스의 "스택"을 가져 와서 $ out 배열에 넣습니다. ($ temp 배열의 사용을 피하는 방법이 있습니까?)

  5. ==============================

    5.

    나는 똑같은 문제에 직면 해있다. 다음은 내가 생각해 낸 것입니다.

    function array_transpose(array $arr)
    {
        $keys    = array_keys($arr);
        $sum     = array_values(array_map('count', $arr));
    
        $transposed = array();
    
        for ($i = 0; $i < max($sum); $i ++)
        {
            $item = array();
            foreach ($keys as $key)
            {
                $item[$key] = array_key_exists($i, $arr[$key]) ? $arr[$key][$i] : NULL;
            }
            $transposed[] = $item;
        }
        return $transposed;
    }
    
  6. ==============================

    6.

    연관 배열을 지원하는 전치 함수가 필요했습니다.

        $matrix = [
            ['one' => 1, 'two' => 2],
            ['one' => 11, 'two' => 22],
            ['one' => 111, 'two' => 222],
        ];
    
        $result = \array_transpose($matrix);
    
        $trans = [
            'one' => [1, 11, 111],
            'two' => [2, 22, 222],
        ];
    

    그리고 돌아 오는 길 :

        $matrix = [
            'one' => [1, 11, 111],
            'two' => [2, 22, 222],
        ];
    
        $result = \array_transpose($matrix);
    
        $trans = [
            ['one' => 1, 'two' => 2],
            ['one' => 11, 'two' => 22],
            ['one' => 111, 'two' => 222],
        ];
    

    array_unshift 트릭이 NOR에서 작동하지 않았습니다 ...

    그래서 나는 레코드 키 연관을 다루기 위해 array_map_join_array 함수를 코딩했다 :

    /**
     * Similar to array_map() but tries to join values on intern keys.
     * @param callable $callback takes 2 args, the intern key and the list of associated values keyed by array (extern) keys.
     * @param array $arrays the list of arrays to map keyed by extern keys NB like call_user_func_array()
     * @return array
     */
    function array_map_join_array(callable $callback, array $arrays)
    {
        $keys = [];
        // try to list all intern keys
        array_walk($arrays, function ($array) use (&$keys) {
            $keys = array_merge($keys, array_keys($array));
        });
        $keys = array_unique($keys);
        $res = [];
        // for each intern key
        foreach ($keys as $key) {
            $items = [];
            // walk through each array
            array_walk($arrays, function ($array, $arrKey) use ($key, &$items) {
                if (isset($array[$key])) {
                    // stack/transpose existing value for intern key with the array (extern) key
                    $items[$arrKey] = $array[$key];
                } else {
                    // or stack a null value with the array (extern) key
                    $items[$arrKey] = null;
                }
            });
            // call the callback with intern key and all the associated values keyed with array (extern) keys
            $res[$key] = call_user_func($callback, $key, $items);
        }
        return $res;
    }
    

    array_transpose가 명확 해졌다.

    function array_transpose(array $matrix)
    {
        return \array_map_join_array(function ($key, $items) {
            return $items;
        }, $matrix);
    }
    
  7. ==============================

    7.

    이처럼 사용

    <?php
    $foo = array(
        'a' => array(
           1 => 'a1',
           2 => 'a2',
           3 => 'a3' 
        ),
        'b' => array(
           1 => 'b1',
           2 => 'b2',
           3 => 'b3' 
        ),
        'c' => array(
           1 => 'c1',
           2 => 'c2',
           3 => 'c3' 
        )
    );
    
    echo "<pre>"; 
    
     $i=0;
     foreach ($foo as $val)
       { $i++;
           $array[$i] = array_column($foo, $i);    
    
       }
       print_r($array);
    
    ?>
    

    결과:

    Array
    (
        [1] => Array
            (
                [0] => a1
                [1] => b1
                [2] => c1
            )
    
        [2] => Array
            (
                [0] => a2
                [1] => b2
                [2] => c2
            )
    
        [3] => Array
            (
                [0] => a3
                [1] => b3
                [2] => c3
            )
    
    )
    
  8. ==============================

    8.

    <?php
    
    $tableau_init = [
        [
            "prenom" => "med",
            "age" => 1
        ],
        [
            "prenom" => "hassan",
            "age" => 2
        ],
        [
            "prenom" => "ali",
            "age" => 3
        ]
    ];
    
    function transpose($tableau){
        $out = array();
    
        foreach ($tableau as $key => $value){
            foreach ($value as $subKey => $subValue){
                $out[$subKey][$key] = $subValue;
            }
        }
    
        echo json_encode($out);
    }
    
    transpose($tableau_init);
    

    이 같은 시도

  9. ==============================

    9.

    시작하기 전에, @quazardus에 두 개의 차원 연관 (또는 비 연관) 배열을 배치하기위한 그의 일반화 된 솔루션을 게시 해 주신 데 대해 다시 한번 감사드립니다.

    가능한 한 간결하게 코드를 작성하는 습관을 가지고 있기 때문에 코드를 좀더 "최소화"하려고했습니다. 이것은 모든 사람의 취향에 맞는 것은 아닙니다. 그러나 누군가가 관심을 가져야하는 경우를 대비해서, 그의 해결책을 생각해 보겠습니다.

    function arrayMap($cb, array $arrays) // $cb: optional callback function
    {   $keys = [];
        array_walk($arrays, function ($array) use (&$keys) 
                            { $keys = array_merge($keys, array_keys($array)); });
        $keys = array_unique($keys); $res = [];
        foreach ($keys as $key) {
          $items = array_map(function ($arr) use ($key)
                             {return isset($arr[$key]) ? $arr[$key] : null; },$arrays);
          $res[$key] = call_user_func(
            is_callable($cb) ? $cb 
                             : function($k, $itms){return $itms;},
            $key, $items);
        }
        return $res;
    }
    

    이제 PHP 표준 함수 인 array_map ()과 비슷하게, 호출 할 때

    arrayMap(null,$b);
    

    원하는 전치 행렬을 얻을 수 있습니다.

  10. from https://stackoverflow.com/questions/797251/transposing-multidimensional-arrays-in-php by cc-by-sa and MIT lisence