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

发布于 2025-01-20 12:26:33 字数 2189 浏览 3 评论 0原文

我有以下工作代码,它从 2 个单独的数组($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 
//              )
//  )
?>

I have the following working code that from 2 separate arrays ($I & $f) creates final multidimension array with the data as associated columns.

The problem is i feel the code is clunky, but i cant see if, or how it could me improved. So I'm hoping a second pair of eyes can help.

<?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 
//              )
//  )
?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若沐 2025-01-27 12:26:33

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

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

方法 1:嵌套 foreach

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

然后,而不是使用 1 for 和 2 foreach< /code> 您可以为每个数组使用 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;
}

Yes, indeed I think the code can be optimised for readability and logic.

I can think of two methods you can use.

Method 1 : nested foreach

First of all, you don't need a foreach to initialize your multidimentional array, you can do it within the main loop you use to read the data. So you can remove the foreach -- $f[] = [$v=>null];

Then, instead of having 1 for and 2 foreach you can just have 2 foreach one for each array and use a very fast strpos to identify if the key matches and populate the final array.

Here's the resulting code.

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

This first method is simple, with a straightforward logic. However it requires a nested foreach. Which means that if both arrays get larger, your code gets much slower.

Method 2 : key manipulation

This method assumes that the keys of the first array never change structure and they are always somestringid_[digits]

In this case we can avoid looping the second array and just use a regular expression to recreate the key.

$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;
}
┈┾☆殇 2025-01-27 12:26:33

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

代码:(演示

$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',
  ),
)

I don't see any need to implement any additional data or conditions. You only need to read your main array, mutate the keys (trim the trailing unique identifiers) as you iterate, and push data into their relative groups.

Code: (Demo)

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

Output:

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',
  ),
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文