将字符串按逗号和竖线分割为两个数组

4
我按照以下方式编写代码,但输出结果错误:
$asst_vicars_data_arr=explode(',',$asst_vicars_data);
$asst_head_type_count=count($asst_vicars_data_arr);

$d = explode("|",$data);
foreach ($asst_vicars_data_arr as $value) {
    $arr = explode("|",$value);
    print_r($arr); 
}

输入:

$asst_vicars_data_arr=Array ( [0] => PT|1 [1] => O|4 [2] => PT|15,... )

期望输出:

$type=Array([0] => PT, [1] => O,...)
$heads=Array([0] => 1, [1] => 4,...)

我应该怎样创建这两个数组?
3个回答

3

本质上,这个问题是一个字符串转数组的练习。与其做大量的explode(),我们来研究一些可以减少迭代函数调用的方法...

方法 #1:使用preg_match()和数组解构的一行代码:

preg_match_all('/([^|]+)\|([^,]+)/', $asst_vicars_data, $m) ? [, $type, $heads] = $m : null;
// output: $type=array(0=>'PT', 1=>'O', 2=>'PT')
// output: $heads=array(0=>'1', 1=>'4', 2=>'15')

方法 #2:使用 preg_split()array_chunk()array_column() 的三行代码

$asst_vicars_data = 'PT|1,O|4,PT|15';
$a = array_chunk(preg_split('/,|\|/', $asst_vicars_data), 2);
$type = array_column($a, 0);  // output: array(0=>'PT', 1=>'O', 2=>'PT')
$heads = array_column($a, 1); // output: array(0=>'1', 1=>'4', 2=>'15')

我的第一个方法使用一个精简的正则表达式模式来提取值,这些值可以很容易地被 list() 设置为变量。 list() 的前导逗号意味着 $m 的第一个子数组(完整字符串)不会被分配变量名。

我的第二种方法使用一个精简的正则表达式模式,在同一步骤中将字符串在管道和逗号上分解。 array_chunk() 将元素成对放置。 最后,array_column() 获取数组中的“垂直”值。

此页面上目前的所有其他回答都在每次迭代中使用 explode() 调用。 随着输入大小的增加,这种方法变得越来越低效。 因此,更有效的方法是进行一次爆炸/拆分,然后从那里继续。

对于这种情况,方法#1 显然是我最喜欢的方法; 我只想展示方法#2 作为一种替代方案,它也在处理碎片之前仅对字符串进行了一次分解。


这里有一些额外的方法,行为类似于其他答案中的 foreach 循环(它们也因为每次迭代调用 explode() 而遭受相同的低效率问题):

array_map() 可以被滥用来编写一个丑陋的单行代码:

$asst_vicars_data = 'PT|1,O|4,PT|15';
array_map(function($a) use(&$type, &$heads) { [$type[], $heads[]] = explode('|', $a); }, explode(',', $asst_vicars_data));
var_export($type);
var_export($heads);

array_walk() 一样的故事,但多了一行代码:

$asst_vicars_data = 'PT|1,O|4,PT|15';
$asst_vicars_data_arr = explode(',', $asst_vicars_data);
array_walk($asst_vicars_data_arr, function($a) use(&$type, &$heads) { [$type[], $heads[]] = explode('|', $a); });
var_export($type);
var_export($heads);

看起来你应该把我回答的问题作为重复问题关闭,而不是反过来? - Nick
在这种情况下,也许你应该在那个页面上提供一些这些解决方案,因为在preg_match版本中使用数组解构是对其他答案的改进。 - Nick
嗯,那样做不道德/体面。我不能删除我的答案。请随意将此处的任何内容添加到您的答案中。我将把该页面视为此主题所有未来重复内容的规范。 - mickmackusa
那么,在这种情况下,我可能会在preg_match代码中添加关于数组解构的注释。 - Nick
有趣的是,在preg_match_all的结果上您不需要条件语句。如果您只是进行直接赋值[, $type, $heads] = $m,如果没有匹配,您将得到两个空数组的预期/期望结果。https://3v4l.org/i8bkA - Nick
显示剩余2条评论

3

希望这能帮到你,我在这里使用explode函数将字符串拆分,并用foreach循环进行操作。

在此处尝试此代码片段

<?php

ini_set('display_errors', 1);
$asst_vicars_data_arr=Array ( 0 => "PT|1",
                              1 => "O|4",
                              2 => "PT|15",
                              3 =>"1|6");
$types=array();
$heads=array();
foreach($asst_vicars_data_arr as $value)
{
    list($types[],$heads[])=explode("|",$value);
}

print_r($types);
print_r($heads);

3
你可以试试这个。
<?php
$asst_vicars_data_arr=array ( 0 => 'PT|1' , 1 => 'O|4' , 2 =>'PT|15');
foreach ($asst_vicars_data_arr as $value) {
    $arr = explode("|",$value);
    $type [] = $arr[0];
    $heads [] = $arr[1];
}
print_r($type);
print_r($heads);
?>

Fiddle


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