减少数组到字符串,避免foreach

时间:2017-04-11 05:57:04

标签: php arrays

我有一个数组要减少为字符串,但我要做 MANY 次,所以我想使用一些数组PHP函数(array_walk,array_reduce,...的某种组合)但没有一个符合我的需求,但我相信这是一个我想念的解决方案。代码也必须符合PHP5.6。

$list =[
    'k1' => 'vA1 vA2 vA2',
    'k2' => 'vB1 vB2 vB2',
    'k3' => '',
    'k4' => 'vC1 vC2 vC2',
    'k5' => NULL,
    'k6' => 'vD1 vD2 vD2',
];

function reduce($list){
    $_buff="";
    $_sep="";
    foreach ($list as $k => $v){
        if($v===null){
            continue;
        }
        $_buff.="$_sep$k $v";
        $_sep="; ";
    }
    return $_buff;
}

echo reduce($list)."\n";

预期结果是

k1 vA1 vA2 vA2; k2 vB1 vB2 vB2; k3 ; k4 vC1 vC2 vC2; k6 vD1 vD2 vD2

如果value为空字符串或 null ,请注意不同的行为。

6 个答案:

答案 0 :(得分:1)

您可以使用array_mapimplode,如:

<div class="bagitem-arrow" id="bagitem-arrow"></div>
<div class="bagitem-main">
  <div class="bagitem-box">
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
    <p>hi hi hi hi h i ih ih i hi hi h ih ih ih i hi hihi h ih ih i hi hi hi </p>
  </div>
</div>

结果是:

  

k1 vA1 vA2 vA2; k2 vB1 vB2 vB2; K3; k4 vC1 vC2 vC2; k6 vD1 vD2 vD2

答案 1 :(得分:1)

这不是答案,而是关于问题和答案的一些想法和数据。

我的目标是避免foreach,因为它很慢。

以一种非常令人惊讶的方式,我的实施是最快的!

正如@kunruh foreach指出的那样,比收集函数更快,并为中间值分配内存

探查器下的代码:

<?php

function filterNull($v) {
    if ($v === null) {
        return false;
    }
    return true;
}

class ProfileSolution
{
    const LOOP_LV1 = 200;
    const LOOP_LV2 = 300;
    public function reduceIvan($list){
        $_buff="";
        $_sep="";
        foreach ($list as $k => $v){
            if($v===null){
                continue;
            }
            $_buff.="$_sep$k $v";
            $_sep="; ";
        }
        return $_buff;
    }
    public function reduceMateiMihai ($list)
    {
        $_list = array_filter($list, function ($value) {
            return $value !== null;
        });

        $array = array_map(function ($key, $value) {
            return trim($key . ' ' . $value);
        }, array_keys($_list), $_list);

        return implode('; ', $array);
    }
    public function reduceMasterFly($list){
        $array = [];
        foreach( $list as $key => $value ){
            $tmp = [];
            if ( !is_null($value) ){
                $tmp[] = $key;
                $tmp[] = $value;
                $array[] = implode(" ", $tmp);
            }
        }
        return implode("; ", $array);
    }
    public function reduceKunruh($list) {
        $result = "";
        foreach ($list as $key => $value) {
            if ($value === NULL) continue;

            $result .= " $key $value;";
        }

        // remove trailing semicolon
        $result = substr($result, 0, -1);

        return $result;
    }
    public function reduceHmmm ($list)
    {
        $result = array();

        array_walk($list, function($value, $key) use (&$result) {
            if($value!==null) {
                $result[] = $key .' '. $value;
            }
        });

        return print_r(implode('; ', $result),true);
    }
    public function reduceAd ($list)
    {
        $filteredList = array_filter($list, 'filterNull');
        return implode("; ", array_map(function($k, $v){
            return "$k $v";
        }, array_keys($filteredList), array_values($filteredList)));
    }

    public function testReduceIvan ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceIvan($list);
        }
    }
    public function testReduceMateiMihai ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceMateiMihai($list);
        }
    }
    public function testReduceMasterFly ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceMasterFly($list);
        }
    }
    public function testReduceKunruh ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceKunruh($list);
        }
    }
    public function testReduceHmmm ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceHmmm($list);
        }
    }
    public function testReduceAD ($list)
    {
        $t=0;
        while($t++ < self::LOOP_LV2){
            $res="";
            $res=$this->reduceAD($list);
        }
    }


    public function run ()
    {
        $list =[
            'k1'    => 'magni dolores eos qui ratione voluptatem sequi nesciunt. Neque',
            'k2'    => 'porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem',
            'k3'    => '',
            'k4'    => 'minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem',
            'k5'    => NULL,
            'k6'  => 'non numquam eius modi tempora incidunt  labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis',
            'k7'  => 'aut fugit, sed quia consequuntur',
            'k8'  => 'sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae',
            'k9'  => 'vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam',
            'k10' => 'nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam',
            'k11' => 'inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor',
            'k12' => 'amet, consectetur, adipisci velit, sed quia',
            'k13' => Null,
            'k14' => 'pain, but because occasionally circumstances occur in which toil and',
            'k15' => 'explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes',
            'k16' => 'amet, consectetur, adipisci velit,  quia',
            'k17' => 'or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter',
            'k18' => 'consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain',
            'k19' => 'voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque',
            'k20' => Null,
            'k21' => 'inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit ',
            'k22' => 'amet, consectetur,  velit, sed quia',
            'k23' => 'laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas',
            'k24'  => 'non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis',
        ];

        $t=0;
        while($t++ < self::LOOP_LV1){
            $this->testReduceIvan($list);
            $this->testReduceMateiMihai($list);
            $this->testReduceMasterFly($list);
            $this->testReduceKunruh($list);
            $this->testReduceHmmm($list);
            $this->testReduceAD($list);
        }



    }

}

$o = new ProfileSolution();
$o->run();

使用demo(请参阅问题)数据调用树 Call tree with demo (see the question) data

使用实际数据量调用树 Call tree with realistic amount of data

答案 2 :(得分:0)

试试这个,

function reduce($list){
    $array = [];
    foreach( $list as $key => $value ){
        $tmp = [];
        if ( !is_null($value) ){
            $tmp[] = $key;
            $tmp[] = $value;
            $array[] = implode(" ", $tmp);
        }
    }
    return implode("; ", $array);
}

答案 3 :(得分:0)

我认为与foreach或任何array_ *函数的执行时间差异不大。只有当记录增加超过100K时才会有用。

$result = array();

array_walk($list, function($value, $key) use (&$result) {
    if($value!==null) {
        $result[] = $key .' '. $value;
    }
});

print_r(implode('; ', $result));

为什么不比较所有答案所花费的时间并选择最佳答案;)

答案 4 :(得分:0)

我认为这是一个非常简洁的解决方案:

function reduce($list) {
    $result = "";
    foreach ($list as $key => $value) {
        if ($value === NULL) continue;

        $result .= " $key $value;";
    }

    // remove trailing semicolon
    $result = substr($result, 0, -1);

    return $result;
}

答案 5 :(得分:-1)

我认为您应该使用array_valuesarray_keysarray_maparray_filterimplode

function filterNull($v) {
    if ($v === null) {
        return false;
    }   
    return true;
}

$filteredList = array_filter($list, 'filterNull');
echo implode("; ", array_map(function($k, $v){
    return "$k $v";
}, array_keys($filteredList), array_values($filteredList)));

array_filter将删除空值。 array_keys将检索密钥。 array_values将检索值。 array_map将处理每个单元格。 implode会将阵列的每个单元粘在一起。

编辑:我已经改变了整个代码,因为我第一次误读了。现在,该解决方案符合您的需求。