返回
二维数组透视与计数:PHP 实现状态转换与零值填充
php
2024-12-15 14:44:57
透视与计数:转换二维数组并填充默认零值列
在处理数据时,我们经常需要对二维数组进行形式转换和聚合操作。本文将探讨一种常见情况:如何透视一个二维数组,并对分组值进行计数,最终生成一个带有默认零值列的新二维数组。
问题分析
给定的二维数组表示用户在不同步骤的状态。目标是将数据透视为以步骤为中心,并统计每个步骤中不同状态的数量,如“accepted”,“refused”和“waiting”。 如果某个步骤没有出现特定状态,则该状态的计数应为零。
解决方案
下面将介绍两种方法来解决这个问题:一种是使用循环迭代,另一种是利用函数式编程思想。
方案一:循环迭代
这种方法通过嵌套循环遍历原始数组,并累加每个状态的计数。
原理:
- 初始化一个空的目标数组,用于存储透视后的结果。
- 遍历原始数组中的每个用户及其步骤状态。
- 对于每个步骤,检查目标数组中是否已存在该步骤的记录。
- 如果不存在,则创建一个新记录,并将所有状态的计数初始化为零。
- 如果存在,则根据当前步骤的状态,增加相应状态计数器的值。
代码示例 (PHP):
<?php
$results = [
"User_1" => [
"Step_1" => "accepted",
"Step_2" => "accepted",
"Step_3" => "waiting",
"Step_4" => "refused"
],
"User_2" => [
"Step_1" => "waiting",
"Step_2" => "accepted",
"Step_3" => "accepted",
"Step_4" => "refused"
],
];
$steps = [];
foreach ($results as $user => $userSteps) {
foreach ($userSteps as $step => $status) {
if (!isset($steps[$step])) {
$steps[$step] = [
'acceptedSum' => 0,
'refusedSum' => 0,
'waitingSum' => 0,
];
}
switch ($status) {
case 'accepted':
$steps[$step]['acceptedSum']++;
break;
case 'refused':
$steps[$step]['refusedSum']++;
break;
case 'waiting':
$steps[$step]['waitingSum']++;
break;
}
}
}
print_r($steps);
?>
操作步骤:
- 将代码保存为
.php
文件 (例如pivot_count.php
)。 - 通过命令行运行:
php pivot_count.php
。
该代码会输出透视后的数组,其中包含每个步骤的“accepted”,“refused”和“waiting”状态计数。
安全建议:
- 确保输入数据格式符合预期,避免出现类型错误。
- 对状态值进行校验,防止出现未定义的状态导致程序逻辑错误。
方案二:函数式编程 (PHP)
这种方法利用 PHP 的数组函数,以更简洁的方式实现相同的逻辑。
原理:
- 使用
array_keys
和array_unique
获取所有可能的状态。 - 初始化状态计数模板。
- 遍历原始数组,使用
array_reduce
累积每个步骤的状态计数。 - 循环遍历步骤,若某个状态没有出现则填补并设值为0。
代码示例 (PHP):
<?php
$results = [
"User_1" => [
"Step_1" => "accepted",
"Step_2" => "accepted",
"Step_3" => "waiting",
"Step_4" => "refused"
],
"User_2" => [
"Step_1" => "waiting",
"Step_2" => "accepted",
"Step_3" => "accepted",
"Step_4" => "refused"
],
];
$statuses = array_unique(array_reduce($results, function($carry, $item){
return array_merge($carry,array_values($item));
},[]));
$statusTemplate = array_reduce($statuses,function($carry,$item){
$carry[$item.'Sum'] = 0;
return $carry;
},[]);
$steps = [];
foreach($results as $userSteps){
foreach($userSteps as $step => $status){
if(!isset($steps[$step])){
$steps[$step] = $statusTemplate;
}
$steps[$step][$status.'Sum']++;
}
}
print_r($steps);
?>
操作步骤:
- 将代码保存为
.php
文件 (例如pivot_count_functional.php
)。 - 通过命令行运行:
php pivot_count_functional.php
。
该代码会产生与方案一相同的输出结果。函数式编程方法通常更简洁、可读性更强,但可能在处理大型数据集时性能略逊于循环迭代方法。
安全建议:
- 类似于方案一,同样需要注意输入数据的格式和状态值的校验。
- 对函数式编程方法中的闭包函数进行充分测试,确保其逻辑正确。
总结
本文介绍了两种将二维数组进行透视并对分组值进行计数的方法,并提供了详细的代码示例和操作步骤。 两种方案都能有效解决问题,开发者可以根据实际需求和个人偏好选择合适的方法。循环迭代方式易于理解和实现,而函数式编程方式则更具代码简洁性和可读性。选择哪种方案取决于具体场景和性能要求。在实际应用中,务必对代码进行充分测试,并注意数据安全性和代码的健壮性。