我正在寻找一种过滤 PHP 多维数组(它是一个表)的方法。 该数组看起来与此类似:
array (
0 =>
array (
'Standort' => '',
'Letzte Meldung' => '',
'On-/Offline seit' => '04.05.2022 11:03',
'Online' => '',
),
1 =>
array (
'Standort' => 'Schweiz',
'Letzte Meldung' => '',
'On-/Offline seit' => '11.02.2022 14:59',
'Online' => '',
),
)
数组内的键每次都是相同的。我的目标是循环遍历每个子数组并删除每个子数组中的任何空键。 我已经尝试过这个:
$table_row_array = array_filter(array_map('array_filter', $table_row_array));
但这不是解决方案,因为有时我的表格行没有匹配的键。
预期结果是:
array (
0 =>
array (
'Standort' => '',
'On-/Offline seit' => '04.05.2022 11:03',
),
1 =>
array (
'Standort' => 'Schweiz',
'On-/Offline seit' => '11.02.2022 14:59',
),
)
循环第一个数组元素的键。对于每个键,使用 array_values 提取该键下的所有值,使它们唯一,然后检查是否只剩下一个,并且它是一个空字符串 - 如果是,则您找到了一个需要删除的键。
然后,循环整个数组,并从各个项目中取消设置这些键。
$data = array (
0 =>
array (
'Standort' => '',
'Letzte Meldung' => '',
'On-/Offline seit' => '04.05.2022 11:03',
'Online' => '',
),
1 =>
array (
'Standort' => 'Schweiz',
'Letzte Meldung' => '',
'On-/Offline seit' => '11.02.2022 14:59',
'Online' => '',
),
);
$emptyKeys = [];
foreach(array_keys($data[0]) as $key) {
$uniqueValues = array_unique(array_column($data, $key));
if(count($uniqueValues) == 1 && $uniqueValues[0] === '') {
$emptyKeys[] = $key;
}
}
foreach($emptyKeys as $emptyKey) {
foreach($data as &$item) { // pass $item by reference here, so that we
// manipulate the original array, and not just a copy
unset($item[$emptyKey]); // remove the key
}
unset($item); // unset the reference itself
}
var_dump($data);
您当然也可以嵌套循环,并去掉额外的
$emptyKeys
数组:
foreach(array_keys($data[0]) as $key) {
$uniqueValues = array_unique(array_column($data, $key));
if(count($uniqueValues) == 1 && $uniqueValues[0] === '') {
foreach($data as &$item) {
unset($item[$key]);
}
unset($item);
}
}
使用 array_flip 切换键和值,取消设置为空,仅适用于一个数组中的不同值,因为相似的值将被覆盖:
$laData = array (
0 =>
array (
'Standort' => '',
'Letzte Meldung' => '',
'On-/Offline seit' => '04.05.2022 11:03',
'Online' => '',
),
1 =>
array (
'Standort' => 'Schweiz',
'Letzte Meldung' => '',
'On-/Offline seit' => '11.02.2022 14:59',
'Online' => '',
),
);
$laResult = array();
foreach($laData as $laSingleData) {
$laSingleData = array_flip($laSingleData);
unset($laSingleData['']);
$laSingleData = array_flip($laSingleData);
$laResult[] = $laSingleData;
}
print_r($laResult);
$input = [
[
'Standort' => '',
'Letzte Meldung' => '',
'On-/Offline seit' => '04.05.2022 11:03',
'Online' => '',
],
[
'Standort' => 'Schweiz',
'Letzte Meldung' => '',
'On-/Offline seit' => '11.02.2022 14:59',
'Online' => '',
]
];
$keys = array_filter(
array_keys($input[0]),
fn($key) => array_filter(array_column($input, $key), fn($value) => !empty($value))
);
$result = array_map(
fn($item) => array_values(array_intersect_key($item, array_flip($keys))),
$input
);
print_r($result);
输出:
Array
(
[0] => Array
(
[0] =>
[1] => 04.05.2022 11:03
)
[1] => Array
(
[0] => Schweiz
[1] => 11.02.2022 14:59
)
)
我不推荐 @FatFreddy 的利用
array_flip()
的方法——这种技术会破坏不应该被破坏的值。
为了添加另一个可行的解决方案,我将展示几个循环——一个用于过滤,一个用于转置。
代码:(演示)
$columns = [];
foreach ($input[0] as $columnName => $value) {
$columnData = array_column($input, $columnName);
if (strlen(implode($columnData))) {
$columns[$columnName] = $columnData;
}
}
$result = [];
foreach ($columns as $colName => $colValues) {
foreach ($colValues as $i => $value) {
$result[$i][$colName] = $value;
}
}
var_export($result);
对于函数式方法,迭代数组中的每个叶节点并收集与任何非空值相关的列名称。然后再次传递输入,以按白名单列名称过滤每行的内容。
代码:(演示)
$keep = [];
array_walk_recursive(
$input,
function($v, $k) use(&$keep) {
if (strlen($v)) {
$keep[$k] = null;
}
}
);
var_export(
$keep ? array_map(fn($row) => array_intersect_key($row, $keep), $input) : []
);