Если вы попытаетесь распаковать образцы данных OP с помощью оператора splat (...
), вы получите:
Неустранимая ошибка: необработанная ошибка: невозможно распаковать массив со строковыми ключами
Proof
Чтобы устранить эту ошибку, позвоните array_values()
, чтобы проиндексировать ключи первого уровня перед распаковкой.
var_export(array_map(null, ...array_values($foo)));
Выход:
array (
0 =>
array (
0 => 'a1',
1 => 'b1',
2 => 'c1',
),
1 =>
array (
0 => 'a2',
1 => 'b2',
2 => 'c2',
),
2 =>
array (
0 => 'a3',
1 => 'b3',
2 => 'c3',
),
)
Еще одна особенность / сюрприз в отношении транспонирования с помощью этой техники заключается в том, что элементы null
будут генерироваться, когда подмассивы имеют разные размеры ... но, возможно, не там, где вы могли бы ожидать.
Из данных примера:
$foo = array(
'a' => array(
1 => 'a1',
2 => 'a2'
),
'b' => array(
1 => 'b1',
3 => 'b3'
),
'c' => array(
1 => 'c1',
2 => 'c2',
3 => 'c3'
)
);
Вывод:
array (
0 =>
array (
0 => 'a1',
1 => 'b1',
2 => 'c1',
),
1 =>
array (
0 => 'a2',
1 => 'b3',
2 => 'c2',
),
2 =>
array (
0 => NULL,
1 => NULL,
2 => 'c3',
),
)
Обратите внимание на уровень заботы, проявляемый функцией (сравнимый с обработчиками багажа, которые вывозят ваш багаж из живота самолета). Не обращают внимания на идентификаторы исходных значений подмассива (и не имеет значения, если бы 1
, 2
, & 3
были x
, y
, & z
); все, что сходит с конвейерной ленты, выбрасывается в самый низкий доступный слот.
Такое поведение является последовательным и надежным в предоставлении полной матрицы. Альтернатива цикла foreach()
не будет изначально доставлять элемент null
из подмассивов разных размеров, и в большинстве реализаций его возможность доступа ко всем значениям подмассива зависит от длины первого подмассива.
$foo = array(
'a' => array(
1 => 'a1',
2 => 'a2'
),
'b' => array(
1 => 'b1',
),
'c' => array(
1 => 'c1',
2 => 'c2',
3 => 'c3'
)
);
foreach (current($foo) as $column => $not_used) {
$result[] = array_column($foo, $column);
}
var_export($result);
Выход:
array (
0 =>
array (
0 => 'a1',
1 => 'b1',
2 => 'c1',
),
1 =>
array (
0 => 'a2',
1 => 'c2',
),
)
Как показано выше, если вы хотите быть уверены, что извлекли ВСЕ данные из входного массива, вам нужно написать логику сложения, чтобы доставить все уникальные идентификаторы столбцов в цикл foreach.
p.s. прежде чем я узнал об этом сокращенном синтаксисе транспонирования, я написал более уродливый, более подробный функциональный транспозитор, который выдержал некоторую критику .