Как сжать / переставить многомерный массив, удалив нулевые значения

У меня есть массив под названием $rows, Первая строка — это заголовок.
Первый столбец X (входной сигнал), остальные столбцы Y1,Y2,Y3и т. д. (выходные сигналы).
Для любого X ценить некоторые из Y значения могут быть NULL,

Я печатаю это с этим кодом:

$first_key = key($rows);
foreach ($rows as $key => $row) {
if($key == $first_key) {    // print header
fputcsv($out, array_keys($row));
}
fputcsv($out, $row);
}

Вывод этого кода выглядит следующим образом (отсортировано по X колонка):

  X   |  Y1  |  Y2  | Y3 |
--------------------------
0.1  |      |  10  |    |
0.5  |  90  |      |  7 |
0.7  |  15  |  40  |    |
1.2  |      |  12  |    |

Цель: реорганизовать вывод, чтобы иметь столбцы X1,Y1,X2,Y2и тд так, что в каждой паре (Xi,Yi) нет NULL(пустые) значения находятся между данными строки и заголовком:

X1    |  Y1  | X2  | Y2 | X3 | Y3 |
------------------------------------------
0.5   |  90  | 0.1 | 10 | 0.5| 7 |
0.7   |  15  | 0.7 | 40 |    |   |
|      | 1.2 | 12 |    |   |

Моя попытка:

$current_header  = array_keys($rows[0]);
$size = count($current_header);
$new_header=array();   // the new header: X1, Y1, X2, Y2,...
$arr_X=array();
$arr_Y=array();
$x_column=$current_header[0];
for ($i=1; $i<$size; $i++) {
$y_column=$current_header[$i];
$new_header[2*$i]   = $x_column;
$new_header[2*$i+1] = $y_column;
$arr_Y[$y_column]   = array_column($rows, $y_column);
$arr_X[$y_column]   = array_column($rows, $x_column);
}

Следующий шаг: присоединиться $arr_X[$y_column] а также $arr_Y[$y_column] в arr_XY, Я думаю, что в этом массиве ключом должен быть индекс (row #); также arr_XY не должны включать точки, где $arr_Y[$y_column] является NULL: я не знаю как это сделать

$arr_XY=array();
for ($i=1; $i<$size; $i++) {
$y_column=$current_header[$i];
// here should be the code to join arrays and eliminate NULL arr_Y points
$arr_XY[$y_column] = ($arr_X[$y_column], $arr_Y[$y_column]);
}

Последний шаг, где мне нужна помощь: создать и распечатать выходные строки, объединив все arr_XY[$y_column] по индексу строки.

3

Решение

Это то, что вы после?

Входные данные:

$rows=[
['X','Y1','Y2','Y3'],
[.1,null,10,null],
[.5,90,null,7],
[.7,15,40,null],
[1.2,null,12,null]
];

Метод:

foreach($rows as $i=>$row){
if(!isset($result)){                       // prepare result keys in order
foreach(array_slice($row,1) as $col){  // don't iterate X column of header
$no=substr($col,1);                // get number following Y
$result["X$no"]=[];                // declare X column with column integer
$result["Y$no"]=[];                // declare Y column with column integer
}
}else{
foreach(array_slice($row,1,null,true) as $i=>$col){  // ignore X column
if(!is_null($col)){                // only store non-null values
$result["X$i"][]=$row[0];      // assign X value
$result["Y$i"][]=$col;         // assign Y value
}
}
}
}
var_export($result);

Альтернативный метод:

foreach($rows as $i=>$row){
foreach(array_slice($row,1,null,true) as $c=>$col){
if($i==0){
$result["X$c"]=[];
$result["Y$c"]=[];
}elseif(!is_null($col)){
$result["X$c"][]=$row[0];
$result["Y$c"][]=$col;
}
}
}

Выход:

array (
'X1' => [0.5, 0.7],
'Y1' => [90, 15],
'X2' => [0.1, 0.7, 1.2],
'Y2' => [10, 40, 12],
'X3' => [0.5],
'Y3' => [7]
];
1

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

Других решений пока нет …