【问题标题】:PHP: flatten multidimensional arrayPHP:展平多维数组
【发布时间】:2009-08-03 14:57:35
【问题描述】:

我需要按“,”然后“:”来爆炸。很简单...

$alttitle = "35:title1,36:title2, 59:title5"
$replacetitles = explode(",",$alttitle);
for ($i = 0 ; $i < count($replacetitles) ; $i++) {
   $replacetitle[] = explode(":", $replacetitles[$i]);
}

产生...

数组 ( [0] => 数组 ( [0] => 35 [1] => title1 ) [1] => 数组 ( [0] => 36 [1] => title2 ) [2] =>数组 ( [0] => 59 [1] => title5 ) )

...但是数字 35,36,59 是唯一的,所以我希望它成为数组的键?

数组([35] => 标题1 [36] => 标题2 [59] => 标题5)

【问题讨论】:

标签: php multidimensional-array


【解决方案1】:

只需在循环时设置它:

$alttitle = "35:title1,36:title2, 59:title5"
$tmptitles = explode(",",$alttitle);

$replacetitle = array();
foreach($tmptitles as $tmptitle) {
   $tmparr = explode(":", trim($tmptitle));
   $replacetitle[intval($tmparr[0])] = trim($tmparr[1]);
}

通过上述方法,您将创建数组的迭代次数最少。

【讨论】:

  • 如果您将trim 添加到$tmparr[0],这将是恕我直言最优雅的解决方案。
  • 嘿,抱歉,我现在的位置似乎有些滞后。如何拆分超过 1 个正确答案?! :)
  • @EddyR:你不能。选择最适合您的,通常是社区选择的。
【解决方案2】:

这是另一种但可能有点矫枉过正的选择。

if (!preg_match_all('/([0-9]+)\s*:\s*([^,]+)/', $alttitle, $matches)) {
    //not valid   
}

$array = array_combine($matches[1], $matches[2]);
print_r($array);

【讨论】:

    【解决方案3】:

    这是我的看法

    $alttitle  = "35:title1,36:title2, 59:title5";
    
    $entries   = preg_split( "/ *, */", $alttitle );
    $flattened = array();
    
    for ( $i = 0, $l = count( $entries ); $i < $l; $i++)
    {
      list( $index, $value ) = explode( ':', $entries[$i] );
      $flattened[$index] = $value;
    }
    
    print_r( $flattened );
    

    编辑

    现在进行速度测试与爆炸/修剪

    $testData = implode( ',', array_fill( 1, 10000, "a,b, c,  d" ) );
    
    $start = microtime( true );
    $entries = explode( ",", $testData );
    $ouptput = array();
    
    for ( $i = 0, $l = count( $entries ); $i < $l; $i++ )
    {
      $output[] = trim( $entries[$i] );
    }
    echo "explode/trim test took: ", ( microtime( true ) - $start ), ' seconds<br>';
    
    unset( $start, $entries, $output );
    
    $start = microtime( true );
    $entries = preg_split( "/ *, */", $testData );
    $ouptput = array();
    
    for ( $i = 0, $l = count( $entries ); $i < $l; $i++ )
    {
      $output[] = $entries[$i];
    }
    echo "preg_split test took: ", ( microtime( true ) - $start ), ' seconds<br>';
    

    【讨论】:

    • preg_split 的性能远不如先爆炸后修剪。
    • 你确定吗?试试我上面发布的测试。
    • @Peter Bailey:您的代码无法处理32:My Nice Book, 57:The Terror Of The Seas, 92: Hello World等输入
    • @Peter Bailey: 为了保持结果与使用trim 相同,您应该使用preg_split( "/\s*,\s*/m", $alttitle );
    • 好吧,从技术上讲,如果我想 100% 模仿 trim(),它需要是 "/[\\s\\r\\n\\0\\x0B]*,[\\s\\r\\n\\0\\x0B]*/" 但我会把这些细节留给 EddyR 练习
    【解决方案4】:

    在你的代码之后你可以添加这个:

    $ar = array();
    for ($i = 0; $i < count($replacetitle); $i++) {
        $ar[$replacetitle[$i][0]] = $replacetitle[$i][1];
    }
    

    【讨论】:

    • 最好养成在循环表达式中不对固定值使用计数(或其他函数)的习惯。 for ($i = 0, $t = count($replacetitle); $i
    • 这可能是效率最低的解决方案之一。您添加了另一个循环来创建您应该首先完成的事情。
    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2012-08-27
    • 2018-02-28
    • 2018-03-31
    • 2011-09-05
    • 2010-11-22
    相关资源
    最近更新 更多