PHP - 如何翻转2D数组的行和列

时间:2022-03-29 09:21:26

Normally I'd be asking how to turn something like this:

通常我会问如何变成这样的东西:

1      2        3
4      5        6
7      8        9
10    11       12

Into this:

进入这个:

1   4   7   10
2   5   8   11
3   6   9   12

But actually I want to turn it into this:

但实际上我想把它变成这样:

1   5   9
2   6   10
3   7   11
4   8   12

In other words, I want to flip the rows and columns, but keep the same "width" and "height" of the new array. I've been stuck on this for over an hour.

换句话说,我想翻转行和列,但保持新数组的“宽度”和“高度”相同。我已经坚持了一个多小时。

This is the function I'm using to do a normal "flip" (the first example):

这是我用来做普通“翻转”的功能(第一个例子):

function flip($arr)
{
    $out = array();

    foreach ($arr as $key => $subarr)
    {
            foreach ($subarr as $subkey => $subvalue)
            {
                 $out[$subkey][$key] = $subvalue;
            }
    }

    return $out;
}

9 个解决方案

#1


10  

Just walk the array in the correct order. Assuming you have relatively small arrays, the easiest solution is just to create a brand new array during that walk.

只需按正确顺序走数组即可。假设您拥有相对较小的阵列,最简单的解决方案就是在该步行期间创建一个全新的阵列。

A solution will be of the form:

解决方案将采用以下形式:

$rows = count($arr);
$cols = count($arr[0]); // assumes non empty matrix
$ridx = 0;
$cidx = 0;

$out = array();

foreach($arr as $rowidx => $row){
    foreach($row as $colidx => $val){
        $out[$ridx][$cidx] = $val;
        $ridx++;
        if($ridx >= $rows){
            $cidx++;
            $ridx = 0;
        }
    }
}

#2


4  

function flip_row_col_array($array) {
    $out = array();
    foreach ($array as  $rowkey => $row) {
        foreach($row as $colkey => $col){
            $out[$colkey][$rowkey]=$col;
        }
    }
    return $out;
}

#3


2  

I had to write this one to inverse an array of name indexed arrays. It's very useful for printing php array as as html table, as it even fills missing elements with nulls so the number of is same for all rows of html table.

我不得不写这一个来反转一个名称索引数组的数组。这对于打印php数组和html表非常有用,因为它甚至用空值填充缺少的元素,因此html表的所有行的数量相同。

  /**
  * Inverses a two dimentional array.
  * The second dimention can be <b>name indexed</b> arrays, that would be preserved.
  * This function is very useful, for example, to print out an html table
  * from a php array.
  * It returns a proper matrix with missing valus filled with null.
  *
  * @param type $arr input 2d array where second dimention can be. <b>name indexed</b>
  * arrays.
  * @return 2d_array returns a proper inverted matrix with missing values filled with
  * nulls
  * @author Nikolay Kitsul
  */
 public static function array_2D_inverse($arr) {
     $out = array();
     $ridx = 0;
     foreach ($arr as $row) {
         foreach ($row as $colidx => $val) {
             while ($ridx > count($out[$colidx]))
                 $out[$colidx][] = null;
             $out[$colidx][] = $val;
         }
         $ridx++;
     }
     $max_width = 0; 
     foreach($out as $v)
          $max_width = ($max_width < count($v)) ? count($v) : $max_width;
     foreach($out as $k => $v){
         while(count($out[$k]) < $max_width)
             $out[$k][] = null;
     }
     return $out;
 }

#4


2  

What you need is:

你需要的是:

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

#5


0  

here you go. It works. :)

干得好。有用。 :)



$input1 = array(1,2,3);
$input2 = array(4,5,6);
$input3 = array(7,8,9);
$input4 = array(10,11,12);

$input = array($input1,$input2,$input3,$input4);

echo "\n input array";print_r($input);

// flipping matrices
$output = array();
$intern = array();

for($row=0; $row lt 4; $row++)
    for($col=0;$col lt 3;$col++)
        $intern[] = $input[$row][$col];

echo "\n intern ";print_r($intern);

// nesting the array
$count = 0;
$subcount = 0;

foreach($intern as $value)
{

    $output[$count][$subcount] = $value;
    $count++;

    if($subcount == 3)
    {
        break;
    }

    if($count == 4)
    {
        $count = 0;
        $subcount++;
    }


}


echo "\n final output ";print_r($output);

#6


0  

I have developed this code, based partially in a solution found here to flatten multidimensional arrays.

我已经开发了这个代码,部分基于这里找到的解决多维数组的解决方案。

Hope it helps!

希望能帮助到你!

/**
 *
 * http://*.com/questions/2289475/converting-php-array-of-arrays-into-single-array
 * @param array $array
 * @return array
 */
function arrayFlatten(array $array)
{
    $flatten = array();
    array_walk_recursive($array, function($value) use(&$flatten)
    {
        $flatten[] = $value;
    });

    return $flatten;
}

/**
 *
 *  Reorders an array to put the results ordered as a "N", instead of a "Z"  
 *
 * @static
 * @param $array Array to be ordered
 * @param $columns Number of columns of the "N"
 * @return void
 */
function ZOrderToNOrder($array, $columns)
{
    $maxRows = ceil(count($array) / $columns);
    $newArray = array();
    $colCounter = 0;
    $rowCounter = 0;
    foreach ($array as $element)
    {
        $newArray[$rowCounter][] = $element;
        $rowCounter++;
        if ($rowCounter == $maxRows)
        {
            $colCounter++;
            $rowCounter = 0;
        }
    }

    return arrayFlatten($newArray);
}

#7


0  

falvarez, the ZOrderToNOrder function does not work correctly when one or more columns have got one more element that other columns (other > 1).

falvarez,当一个或多个列有一个或多个其他列的元素(其他> 1)时,ZOrderToNOrder函数无法正常工作。

i think this code fix it:

我认为这段代码修复了它:

public static function ZOrderToNOrder($array, $columns) {
    $numElements = count($array);

    $maxRows = array();
    for ($i = 0; $i < $columns; $i++) {
        $maxRows[$i] = intval(ceil(($numElements - $i) / $columns));
    }

    $newArray = array();

    $rowCounter = 0;
    $colCounter = 0;
    foreach ($array as $element) {
        $newArray[$rowCounter][$colCounter] = $element;
        $rowCounter++;
        if ($rowCounter === $maxRows[$colCounter]) {
            $rowCounter = 0;
            $colCounter++;
        }
    }

    return self::arrayFlatten($newArray);
}

Regards,

问候,

Armando

阿曼多

#8


0  

Modified version of the "accepted" answer, which works MUCH better IMHO:

修改后的“已接受”答案的版本,效果更好恕我直言:

function array2DFlip($arr) {
 if(!is_array($arr) || count($arr) < 1 || !isset($arr[0])) return array();

 $out = array();

 foreach($arr as $row_id => $row){
    foreach($row as $col_id => $val){
        $out[$col_id][$row_id] = $val;
    }
 }

 return $out;
}

#9


0  

Got this simple one:

得到这个简单的一个:

$matrix = [
  [1, 2, 3],
  [1, 2, 3],
  [1, 2, 3],
];

$flipped = array_map(function($col, $i) use($matrix){
  return array_map(function($row) use($matrix, $i){
    return $row[$i];
  }, $matrix);
}, $matrix, array_keys($matrix));

#1


10  

Just walk the array in the correct order. Assuming you have relatively small arrays, the easiest solution is just to create a brand new array during that walk.

只需按正确顺序走数组即可。假设您拥有相对较小的阵列,最简单的解决方案就是在该步行期间创建一个全新的阵列。

A solution will be of the form:

解决方案将采用以下形式:

$rows = count($arr);
$cols = count($arr[0]); // assumes non empty matrix
$ridx = 0;
$cidx = 0;

$out = array();

foreach($arr as $rowidx => $row){
    foreach($row as $colidx => $val){
        $out[$ridx][$cidx] = $val;
        $ridx++;
        if($ridx >= $rows){
            $cidx++;
            $ridx = 0;
        }
    }
}

#2


4  

function flip_row_col_array($array) {
    $out = array();
    foreach ($array as  $rowkey => $row) {
        foreach($row as $colkey => $col){
            $out[$colkey][$rowkey]=$col;
        }
    }
    return $out;
}

#3


2  

I had to write this one to inverse an array of name indexed arrays. It's very useful for printing php array as as html table, as it even fills missing elements with nulls so the number of is same for all rows of html table.

我不得不写这一个来反转一个名称索引数组的数组。这对于打印php数组和html表非常有用,因为它甚至用空值填充缺少的元素,因此html表的所有行的数量相同。

  /**
  * Inverses a two dimentional array.
  * The second dimention can be <b>name indexed</b> arrays, that would be preserved.
  * This function is very useful, for example, to print out an html table
  * from a php array.
  * It returns a proper matrix with missing valus filled with null.
  *
  * @param type $arr input 2d array where second dimention can be. <b>name indexed</b>
  * arrays.
  * @return 2d_array returns a proper inverted matrix with missing values filled with
  * nulls
  * @author Nikolay Kitsul
  */
 public static function array_2D_inverse($arr) {
     $out = array();
     $ridx = 0;
     foreach ($arr as $row) {
         foreach ($row as $colidx => $val) {
             while ($ridx > count($out[$colidx]))
                 $out[$colidx][] = null;
             $out[$colidx][] = $val;
         }
         $ridx++;
     }
     $max_width = 0; 
     foreach($out as $v)
          $max_width = ($max_width < count($v)) ? count($v) : $max_width;
     foreach($out as $k => $v){
         while(count($out[$k]) < $max_width)
             $out[$k][] = null;
     }
     return $out;
 }

#4


2  

What you need is:

你需要的是:

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

#5


0  

here you go. It works. :)

干得好。有用。 :)



$input1 = array(1,2,3);
$input2 = array(4,5,6);
$input3 = array(7,8,9);
$input4 = array(10,11,12);

$input = array($input1,$input2,$input3,$input4);

echo "\n input array";print_r($input);

// flipping matrices
$output = array();
$intern = array();

for($row=0; $row lt 4; $row++)
    for($col=0;$col lt 3;$col++)
        $intern[] = $input[$row][$col];

echo "\n intern ";print_r($intern);

// nesting the array
$count = 0;
$subcount = 0;

foreach($intern as $value)
{

    $output[$count][$subcount] = $value;
    $count++;

    if($subcount == 3)
    {
        break;
    }

    if($count == 4)
    {
        $count = 0;
        $subcount++;
    }


}


echo "\n final output ";print_r($output);

#6


0  

I have developed this code, based partially in a solution found here to flatten multidimensional arrays.

我已经开发了这个代码,部分基于这里找到的解决多维数组的解决方案。

Hope it helps!

希望能帮助到你!

/**
 *
 * http://*.com/questions/2289475/converting-php-array-of-arrays-into-single-array
 * @param array $array
 * @return array
 */
function arrayFlatten(array $array)
{
    $flatten = array();
    array_walk_recursive($array, function($value) use(&$flatten)
    {
        $flatten[] = $value;
    });

    return $flatten;
}

/**
 *
 *  Reorders an array to put the results ordered as a "N", instead of a "Z"  
 *
 * @static
 * @param $array Array to be ordered
 * @param $columns Number of columns of the "N"
 * @return void
 */
function ZOrderToNOrder($array, $columns)
{
    $maxRows = ceil(count($array) / $columns);
    $newArray = array();
    $colCounter = 0;
    $rowCounter = 0;
    foreach ($array as $element)
    {
        $newArray[$rowCounter][] = $element;
        $rowCounter++;
        if ($rowCounter == $maxRows)
        {
            $colCounter++;
            $rowCounter = 0;
        }
    }

    return arrayFlatten($newArray);
}

#7


0  

falvarez, the ZOrderToNOrder function does not work correctly when one or more columns have got one more element that other columns (other > 1).

falvarez,当一个或多个列有一个或多个其他列的元素(其他> 1)时,ZOrderToNOrder函数无法正常工作。

i think this code fix it:

我认为这段代码修复了它:

public static function ZOrderToNOrder($array, $columns) {
    $numElements = count($array);

    $maxRows = array();
    for ($i = 0; $i < $columns; $i++) {
        $maxRows[$i] = intval(ceil(($numElements - $i) / $columns));
    }

    $newArray = array();

    $rowCounter = 0;
    $colCounter = 0;
    foreach ($array as $element) {
        $newArray[$rowCounter][$colCounter] = $element;
        $rowCounter++;
        if ($rowCounter === $maxRows[$colCounter]) {
            $rowCounter = 0;
            $colCounter++;
        }
    }

    return self::arrayFlatten($newArray);
}

Regards,

问候,

Armando

阿曼多

#8


0  

Modified version of the "accepted" answer, which works MUCH better IMHO:

修改后的“已接受”答案的版本,效果更好恕我直言:

function array2DFlip($arr) {
 if(!is_array($arr) || count($arr) < 1 || !isset($arr[0])) return array();

 $out = array();

 foreach($arr as $row_id => $row){
    foreach($row as $col_id => $val){
        $out[$col_id][$row_id] = $val;
    }
 }

 return $out;
}

#9


0  

Got this simple one:

得到这个简单的一个:

$matrix = [
  [1, 2, 3],
  [1, 2, 3],
  [1, 2, 3],
];

$flipped = array_map(function($col, $i) use($matrix){
  return array_map(function($row) use($matrix, $i){
    return $row[$i];
  }, $matrix);
}, $matrix, array_keys($matrix));