如何通过前缀将PHP数组项分离

3
我想在PHP数组中,根据共同前缀将它们分开。
$data = ['status.1', 'status.2', 'status.3',
         'country.244', 'country.24', 'country.845',
         'pm.4', 'pm.9', 'pm.6'];

我希望你能将它们放在单独的变量中,比如$status, $countries, $pms,它们包含以下内容:
$status = [1,2,3];
$country = [244, 24, 845]
$pms = [4,9,6]

我的当前代码需要1.5秒来对它们进行分组:

$statuses = [];
$countries = [];
$pms = [];
$start = microtime(true);
foreach($data as $item){
    if(strpos($item, 'status.') !== false){
        $statuses[]= substr($item,7);
    }

    if(strpos($item, 'country.') !== false){
        $countries[]= substr($item,8);
    }

    if(strpos($item, 'pm.') !== false){
        $pms[]= substr($item,3);
    }
}
$time_elapsed_secs = microtime(true) - $start;
print_r($time_elapsed_secs);

我想知道是否有更快的方法来完成这个任务。


1
你只会有那三个前缀,还是它是动态的前缀? - dWinder
你可以使用asort($data)来提高循环性能。 - McBern
1
我将有5个前缀,如状态,国家,pm,研究类型和日期。 - Pankaj Jha
7个回答

5
这将为您提供更多动态前缀的结果 - 首先使用分隔符拆分,然后按键插入到结果数组中。
要分隔值,您可以使用:extract 请考虑以下代码:
$data = array('status.1','status.2','status.3', 'country.244', 'country.24', 'country.845', 'pm.4','pm.9', 'pm.6');

$res = array();
foreach($data as $elem) {
    list($key,$val) = explode(".", $elem, 2);
    $res[$key][] = $val;

}
extract($res); // this will separate to var with the prefix name

echo "Status is: " . print_r($status); // will output array of ["1","2","3"]

这段代码执行时间不到0.001秒...感谢@mickmackusa简化代码。

3

在每个if语句中添加continue,这样如果它是其中之一,就不会再运行其他的。对于最后一个循环并不是必需的,因为循环显然会重新开始。这样做可以节省一点时间,但可能不会像您想要的那样多。

foreach($data as $item){
    if(strpos($item, 'status.') !== false){
        $statuses[]= substr($item,7);
        continue;
    }

    if(strpos($item, 'country.') !== false){
        $countries[]= substr($item,8);
       continue;
    }

    if(strpos($item, 'pm.') !== false){
        $pms[]= substr($item,3);
        continue;
    }
}

3
我会用explode来分割它们。
类似这样:
$arr = array("status" => [],"country" => [],"pm" => []);
foreach($data as $item){
    list($key,$val) = explode(".",$item);
    $arr[$key][] = $val;
}
extract($res); // taken from david's answer

而且这是一种更易读的代码(在我看来)

___ 编辑 ____

正如@DavidWinder评论的那样,这既不是动态的,也不会导致不同的变量 - 查看他的答案以获取您问题的最完整解决方案。


请注意,这忽略了 OP 的请求:“我希望它们每个都在单独的变量中”,请在您的答案中使用 extract(我试图更动态地回答这个问题...) - dWinder
@DavidWinder - 正确,你的回答是最完整的。 - Jameson the dog

0

在解构时,您可以将数据推入它们各自的组中。唯一的迭代函数调用是explode()

为每个组创建单独的变量是数组数据的设计缺陷/管理不善。

代码:(演示

$result = [];
foreach ($data as $value) {
    [$prefix, $result[$prefix][]] = explode('.', $value, 2);
}
var_export($result);

输出:

array (
  'status' => 
  array (
    0 => '1',
    1 => '2',
    2 => '3',
  ),
  'country' => 
  array (
    0 => '244',
    1 => '24',
    2 => '845',
  ),
  'pm' => 
  array (
    0 => '4',
    1 => '9',
    2 => '6',
  ),
)

如果您想将数字值直接/显式转换为整数,请使用sscanf()演示


0
使用Explode。此外,使用$limit参数可以提高性能并避免在值中有其他'.'时出现错误行为。
$arr = [];
foreach($data as $item){
    list($key,$val) = explode('.', $item, 2);
    if (!$key || !$val) continue;
    $arr[$key][] = $val;
}
var_dump($arr); 

0

我不确定这是否会提高性能,但您可以以每行都有标题和相应值的方式重新排列数组,然后使用array_column()来分组您想要的数据。

以下是如何以这种方式对数据进行分组的示例。(PHP 7.1.25+)

$groupedData = array_map(function($arg) {
    [$key, $val] = explode('.', $arg); # for PHP 5.6 < 7.1.25 use list($key, $val) = explode(...)
    return array($key => $val);
}, $data);

然后,您可以像这样提取所有国家ID:

$countries = array_column($groupedData, 'country');

这里有一个实时演示


0

如果是我,我会这样做...

<?php

$data = array ('status.1', 'status.2', 'status.3',
         'country.244', 'country.24', 'country.845',
         'pm.4', 'pm.9', 'pm.6');

$out = array ();

foreach ( $data AS $value )
{
    $value = explode ( '.', $value );

    $out[$value[0]][] = $value[1];
}

print_r ( $out );

?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接