【问题标题】:Multidimensional array from string来自字符串的多维数组
【发布时间】:2012-04-24 19:13:08
【问题描述】:

假设我有一个想要放入多维数组的字符串。

编辑:字符串中的子文件夹数量是动态的..从零个子文件夹到10个

<?php
       $string ="Folder1/Folder2/Folder3/filename1\n";
       $string .=" Folder1/Folder2/Folder3/filename2\n";
       $string .=" Folder4/Folder2/Folder3/filename3\n";
?>

我想要返回以下数组

<?php
 Array
(
    [Folder1] => Array
        (
            [Folder2] => Array
                (
                    [Folder3] => Array
                        (
                            [0] => filename1
                            [1] => filename2
                        )

                )

        )

    [Folder4] => Array
        (
            [Folder2] => Array
                (
                    [Folder3] => Array
                        (
                            [0] => filename3
                        )

                )

        )

)
?>

最有效的方法是什么?

为了好玩,假设这个数组将被发送到世界的另一端,它想要返回一个字符串。我们该怎么做呢?

【问题讨论】:

  • 好吧,如果你有一个字符串,而你最终想要一个字符串,为什么还要一个数组呢?
  • 因为有些人想将其输出为数组,有些人想将其保存为数据库中的字符串。发送两者都是一种选择,但效率不高。
  • @Paolo_Mulder 当您的输入字符串中有无路径文件名时,请发布您想要的输出。这是一个有趣的问题,但我认为您需要有一个包罗万象的父数组来保存无路径文件名。这就是我要玩的东西:3v4l.org/UGK0l

标签: php arrays multidimensional-array


【解决方案1】:

您可以从 这个类(链接不再可用) 中借用一些代码,特别是 _processContentEntry 方法。

这是完成这项工作的方法的修改版本:

function stringToArray($path)
{
    $separator = '/';
    $pos = strpos($path, $separator);

    if ($pos === false) {
        return array($path);
    }

    $key = substr($path, 0, $pos);
    $path = substr($path, $pos + 1);

    $result = array(
        $key => stringToArray($path),
    );

    return $result;
}

输出

var_dump(stringToArray('a/b/c/d'));

array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    array(1) {
      ["c"]=>
      array(1) {
        [0]=>
        string(1) "d"
      }
    }
  }
}

我想这就是你需要的:)


更新

根据您的评论,以下是处理由换行符分隔的字符串的方法:

$string = "Folder1/Folder2/Folder3/filename1\n";
$string .= " Folder1/Folder2/Folder3/filename2\n";
$string .= " Folder4/Folder2/Folder3/filename3\n";

// split string into lines
$lines = explode(PHP_EOL, $string);

// trim all entries
$lines = array_map('trim', $lines);

// remove all empty entries
$lines = array_filter($lines);

$output = array();

// process each path
foreach ($lines as $line) {
    // split each line by /
    $struct = stringToArray($line);

    // merge new path into the output array
    $output = array_merge_recursive($output, $struct);
}

print_r($output);

附: 要将此数组转换为字符串,只需调用json_encode,但我认为没有理由将其转换为数组然后再转换回原来的样子。

【讨论】:

  • 这将返回一个不同的数组。我的示例不包含 3 个字符串,而是 1 个由 3 行组成的字符串。自己试试。但是感谢您指出正确的方向。
  • 添加了处理多行字符串的代码。现在它会输出与您需要的完全相同的数组。
【解决方案2】:

这可以通过另一种方式递归解决,方法是从数组的开头获取项目,当到达最后一个项目时返回它。

function make_tree( $arr ){
   if( count($arr) === 1){
      return array_pop( $arr );
   }else{
      $result[ array_shift( $arr )] = make_tree( $arr ) ; 
   }
   return $result;
}

$string  = "Folder1/Folder2/Folder3/filename1\n";
$string .= "Folder1/Folder2/Folder3/filename2\n";
$string .= "Folder4/Folder2/Folder3/filename3\n";

$string = trim( $string );

$files_paths = explode( PHP_EOL, $string);

$result = [];

foreach ($files_paths as $key => $value) {
   $parted = explode( '/', $value );
   $tree = make_tree( $parted );
   $result = array_merge_recursive( $result, $tree );
   
}
var_dump( $result );

【讨论】:

    【解决方案3】:

    我认为这是你想要的,

    $string ="Folder1/Folder2/Folder3/filename1\n";
    $string .="Folder1/Folder2/Folder3/filename2\n";
    $string .="Folder4/Folder2/Folder3/filename3\n";
    
    
    $string_array_1 = explode("\n", $string);
    
    $array_need = array();
    
    foreach($string_array_1 as $array_values)
    {
            if($array_values)
            {
                $folders =  explode("/", $array_values);
                $array_need[$folders[0]][$folders[1]][$folders[2]][] = $folders[3];
            }
        }
    
    print_r($array_need);
    

    【讨论】:

    • 它很棒,但不是动态的。如果子文件夹的数量发生变化 Folder5/Folder2/Folder3/Folder4/filename4
    猜你喜欢
    • 2014-05-27
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2014-04-18
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    相关资源
    最近更新 更多