通过键的前导部分对数据进行分组,并将值作为索引元素推送到每组中



我有以下工作代码,它从两个单独的数组($I&$f(创建最终的多维数组,数据作为相关列。

问题是,我觉得代码很笨重,但我不知道它是否或如何改进。所以我希望第二双眼睛能有所帮助。

<?php
//main array of input data
$i = [  'input_tickettype1_storeno_00' => null,
'input_tickettype1_deliverydate_00' => null,
'input_tickettype1_ticketref_00' => null,
'input_tickettype1_storeno_01' => '9874',
'input_tickettype1_deliverydate_01' => '2022-02-01',
'input_tickettype1_ticketref_01' => 'EDN6547',
'input_tickettype1_storeno_02' => '8547',
'input_tickettype1_deliverydate_02' => '2022-01-31',
'input_tickettype1_ticketref_02' => 'EDN5473',
'input_tickettype1_storeno_03' => '9214',
'input_tickettype1_deliverydate_03' => '2022-02-28',
'input_tickettype1_ticketref_03' => 'EDN1073'
];  
//headers
$h = [  'input_tickettype1_storeno' ,
'input_tickettype1_deliverydate',
'input_tickettype1_ticketref'
];
//final multidim array
$f = array();
//Create a multidim for the headers and the values
foreach ($h as $k => $v)
{
$f[] = [$v=>null];
}
//loop throught the headers looping for matches in the input data
for ($x = 0; $x < count($f); $x++) {
foreach ($f[$x] as $fk => $fv) {
foreach ($i as $ik => $iv) {
if  (str_contains($ik,$fk)) {
array_push($f[$x],$iv);
} 
}
}
}
print_r($f);
//Actual Working Output
// Array ( 
//  [0] => Array ( [input_tickettype1_storeno] => 
//                  [0] => 
//                  [1] => 9874 
//                  [2] => 8547 
//                  [3] => 9214 
//              ) 
//  [1] => Array ( [input_tickettype1_deliverydate] => 
//                  [0] => 
//                  [1] => 2022-02-01 
//                  [2] => 2022-01-31 
//                  [3] => 2022-02-28 
//              ) 
//  [2] => Array ( [input_tickettype1_ticketref] => 
//                  [0] => 
//                  [1] => EDN6547 
//                  [2] => EDN5473 
//                  [3] => EDN1073 
//              )
//  )
?>

是的,我确实认为代码可以在可读性和逻辑性方面进行优化。

我能想到你可以用的两种方法。

方法1:嵌套foreach

首先,您不需要foreach来初始化多维数组,您可以在用于读取数据的主loop中进行初始化。因此,您可以移除foreach -- $f[] = [$v=>null];

然后,不需要1个for和2个foreach,每个阵列只需要2个foreach,并使用非常快速的strpos来识别密钥是否匹配并填充最终阵列。

这是生成的代码。

$f = [];
foreach ($h as $prefix) {
$f[$prefix] = [];
foreach ($i as $key => $val) {
if (strpos($key, $prefix) === 0) {
$f[$prefix][] = $val;
}
}
}

第一种方法很简单,逻辑很简单。然而,它需要嵌套foreach。这意味着,如果两个数组都变大,代码就会变慢。

方法2:按键操作

该方法假设第一个数组的密钥永远不会改变结构,并且它们总是somestringid_[digits]

在这种情况下,我们可以避免循环第二个数组,只需使用正则表达式来重新创建键。

$f = [];
foreach ($i as $key => $value) {
preg_match('/^(.*)_[0-9]+$/', $key, $m);
$key = $m[1];
if (empty($f[$m[1]])) {
$f[$m[1]] = [];
}
$f[$m[1]][] = $value;
}

我认为没有必要实现任何额外的数据或条件。您只需要读取主数组,在迭代时更改键(修剪尾部的唯一标识符(,并将数据推送到它们的相对组中。

代码:(演示(

$result = [];
foreach ($array as $k => $v) {
$result[preg_replace('/_d+$/', '', $k)][] = $v;
}
var_export($result);

输出:

array (
'input_tickettype1_storeno' => 
array (
0 => NULL,
1 => '9874',
2 => '8547',
3 => '9214',
),
'input_tickettype1_deliverydate' => 
array (
0 => NULL,
1 => '2022-02-01',
2 => '2022-01-31',
3 => '2022-02-28',
),
'input_tickettype1_ticketref' => 
array (
0 => NULL,
1 => 'EDN6547',
2 => 'EDN5473',
3 => 'EDN1073',
),
)

最新更新