array_map将两个回调函数映射为一个函数


array_map two callback functions as one

这是我的代码:

$sc = 'hello 8491241 some text 6254841 some text 568241 414844:412';
preg_match_all('/[0-9]{5,10}/', $sc, $matches1);
preg_match_all('/[0-9]{5,10}:[0-9]{1,5}/', $sc, $matches2);
function cub1($match)
{
    return array(
      'batch' => $match,
      'type' => '1',
    );
}
function cub2($match)
{
    return array(
      'batch' => $match,
      'type' => '2',
    );
}
$pr_matches1 = array_map('cub1', $matches1[0]);
$pr_matches2 = array_map('cub2', $matches2[0]);
$all_matches = array_merge($pr_matches1,$pr_matches2);

它工作得很好,我在问是否可以改进我的代码,并将array_map回调函数(cub1和cub2)作为一个函数(cub),我只需要为$matches1和$matches2 设置不同的"类型"

你知道吗?

是的,这是可能的,只是在函数中识别它来自哪个数组有点棘手。但这应该对你有效:

(这里我只使用strpos()来识别它是匹配形式$matches1还是来自$matches2,因为只有第二个数组可以包含:

<?php
    $sc = 'hello 8491241 some text 6254841 some text 568241 414844:412';
    preg_match_all('/[0-9]{5,10}/', $sc, $matches1);
    preg_match_all('/[0-9]{5,10}:[0-9]{1,5}/', $sc, $matches2);
    function cub($m) {
        if(strpos($m, ":") !== FALSE) {
            return array(
              'batch' => $m,
              'type' => '2',
            );
        } else {
            return array(
              'batch' => $m,
              'type' => '1',
            );
        }

    }
    $all_matches = array_map("cub", array_merge($matches1[0], $matches2[0]));
    print_r($all_matches);
?>

输出:

Array ( [0] => Array ( [batch] => 8491241 [type] => 1 ) [1] => Array ( [batch] => 6254841 [type] => 1 ) [2] => Array ( [batch] => 568241 [type] => 1 ) [3] => Array ( [batch] => 414844 [type] => 1 ) [4] => Array ( [batch] => 414844:412 [type] => 2 ) )

我会把整个事情简化为:

$sc = 'hello 8491241 some text 6254841 some text 568241 414844:412';
preg_match_all('/([0-9]{5,10})(:[0-9]{1,5})?/', $sc, $matches, PREG_SET_ORDER);
$all_matches = array_reduce($matches, function (array $all, array $match) {
    $all[] = ['batch' => $match[1], 'type'  => '1'];
    if (isset($match[2])) {
        $all[] = ['batch' => $match[0], 'type' => '2'];
    }
    return $all;
}, []);

使用一个可选的捕获组,而不是两个单独的regexen,然后区分这两种类型的结果就变得像检查捕获组的存在一样简单。

一些功能性的东西

$sc = 'hello 8491241 some text 6254841 some text 568241 414844:412';
preg_match_all('/[0-9]{5,10}/', $sc, $matches1);
preg_match_all('/[0-9]{5,10}:[0-9]{1,5}/', $sc, $matches2);
$my_matches[1] = $matches1[0];
$my_matches[2] = $matches2[0];
$cub[1] = function($match)
    {
    return array(
        'batch' => $match,
        'type' => '1',
    );
    };
$cub[2] = function($match)
    {
    return array(
        'batch' => $match,
        'type' => '2',
    );
    };
$result = call_user_func_array('array_merge', array_map(function($a, $b)
        { return array_map($a, $b); }, $cub, $my_matches));
var_dump($result);

演示

因此,您需要两个长度任意(但相同)的数组:值数组和回调数组。