массивы — создать транспонированную матрицу, используя переполнение стека

Например, если матрица:

1 2
3 4
5 6

Тогда транспонировать вышеуказанную матрицу будет:

1 3 5
2 4 6

Это мой текущий код:

<?php

// transpose matrix
$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);

foreach ($trans as $key => $val){
foreach ($trans[$key] as $k => $v){
echo $v;
}
}

?>

6

Решение

Есть изворотливый способ PHP перенести 2d массив:

$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);

array_unshift($trans, null);
$trans = call_user_func_array('array_map', $trans);
var_dump($trans);

демонстрация

РЕДАКТИРОВАТЬ Более простой подход с использованием распаковки массива PHP 5.6

С введением функции распаковки аргументов массива в PHP 5.6 мы можем упростить это еще больше:

$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);

$trans = array_map(null, ...$trans);
var_dump($trans);

РЕДАКТИРОВАТЬ объяснение

Цитирование из документации PHP для функция array_map ():

Интересное использование этой функции заключается в создании массива массивов, который может быть легко выполнен с использованием NULL в качестве имени функции обратного вызова.

(См. Пример № 4 на этой странице документации для примера того, что это делает)

array_unshift($trans, null) что мы выполняем в первую очередь, обеспечивает обратный вызов NULL, и мы используем call_user_func_array() потому что мы не обязательно знаем, сколько ценностей в нашем $trans массив. Что мы делаем, используя это call_user_func_array() является эквивалентом:

$trans = array_map(NULL, $trans[0], $trans[1], $trans[2]);

для вашего примера массива, потому что верхний уровень вашего 2-го массива имеет три элемента (ключи 0, 1 и 2).

По сути, этот обратный вызов NULL циклически проходит по всем массивам параллельно, беря каждое значение из них по очереди для создания нового массива:

$maxArraySize = max(count($array[0], $array[1], $array[2]);
// $maxArraySize will have a value of 2 in your case,
//     because your sub-arrays are all equal size
$newArray = [];
for($i = 0; $i < $maxArraySize; ++$i) {
$tmpArray = [];
$tmpArray[] = $array[0][$i];
$tmpArray[] = $array[1][$i];
$tmpArray[] = $array[2][$i];
$newArray[] = $tmpArray[];
}

Там есть пара дополнительных проверок

  • его не волнует, являются ли ваши массивы ассоциативными или перечисляются в любом измерении, потому что он обращается к $iэлемент, а не индекс
  • Если под-массивы не имеют одинаковую длину, тогда эффективные дополнения к более коротким под-массивам будут иметь нулевые значения, чтобы соответствовать длине самого длинного
  • Неважно, сколько массивов вы передадите, все они будут работать параллельно
16

Другие решения

Я считаю, что это работает и с прямоугольными массивами.
Трюк: return array_map(null, ...$squareArray); кажется, работает неожиданным образом для одного столбца массива

function RotateSquare2DArray($squareArray)
{

if ($squareArray == null) { return null; }
$rotatedArray = array();
$r = 0;

foreach($squareArray as $row) {
$c = 0;
if (is_array($row)) {
foreach($row as $cell) {
$rotatedArray[$c][$r] = $cell;
++$c;
}
}
else $rotatedArray[$c][$r] = $row;
++$r;
}
return $rotatedArray;
}

Если массив ассоциативный, я использую это

function RotateSquareAssociativeArray($squareArray)
{
if ($squareArray == null) { return null; }
$rotatedArray = array();
$r = 0;

foreach($squareArray as $c=>$row) {
if (is_array($row)) {
foreach($row as $key=>$cell) {
$rotatedArray[$key][$c] = $cell;
}
}
else {
$rotatedArray[$c][$r] = $row;
}
++$r;
}
return $rotatedArray;
}
0

По вопросам рекламы [email protected]