从列表字符串生成多维数组

时间:2017-02-14 12:25:05

标签: php arrays recursion

我想通过以下方法在PHP中生成一个多维数组 -

- Item 1
-- Item 1.1
-- Item 1.2
--- Item 1.2.1
--- Item 1.2.2
---- Item 1.2.2.1
- Item 2
- Item 3
- Item 4
-- Item 4.1
-- Item 4.2

我最终的目标是将此字符串转换为无序列表。

我认为最好的方法是创建一个递归函数。在一个美好的一天,我相信我可以解决这个问题,但我有一点空白!

数组结构应该类似于下面的转储 -

array(6) {
  [0]=>
  string(6) "Item 1"
  [1]=>
  array(3) {
    [0]=>
    string(8) "Item 1.1"
    [1]=>
    string(8) "Item 1.2"
    [2]=>
    array(3) {
      [0]=>
      string(10) "Item 1.2.1"
      [1]=>
      string(10) "Item 1.2.2"
      [2]=>
      array(1) {
        [0]=>
        string(12) "Item 1.2.2.1"
      }
    }
  }
  [2]=>
  string(6) "Item 2"
  [3]=>
  string(6) "Item 3"
  [4]=>
  string(6) "Item 4"
  [5]=>
  array(2) {
    [0]=>
    string(8) "Item 4.1"
    [1]=>
    string(8) "Item 4.2"
  }
}

希望你能提供帮助。

1 个答案:

答案 0 :(得分:2)

以下内容将直接转换为HTML而不递归:

$text = array();
$text[] = '- Item 1';
$text[] = '-- Item 1.1';
$text[] = '-- Item 1.2';
$text[] = '--- Item 1.2.1';
$text[] = '--- Item 1.2.2';
$text[] = '---- Item 1.2.2.1';
$text[] = '- Item 2';
$text[] = '- Item 3';
$text[] = '- Item 4';
$text[] = '-- Item 4.1';
$text[] = '-- Item 4.2';

$previous_dash_count = 0; // topmost parent
foreach ($text as $line) {
    if (preg_match('/(^\-+)(.*)/', $line, $matches, PREG_OFFSET_CAPTURE)===1) {
        $dash_count = strlen($matches[1][0]);
        $title = $matches[2][0];

        if ($dash_count == $previous_dash_count) {
            echo "<li>$title</li>\n";
        } elseif ($dash_count > $previous_dash_count) {
            echo str_repeat("<ul>\n", $dash_count - $previous_dash_count);
            echo "<li>$title</li>\n";
        } else {
            echo str_repeat("</ul>\n",$previous_dash_count-$dash_count+1);
            echo "<ul>\n";
            echo "<li>$title</li>\n";
        }

        $previous_dash_count = $dash_count;
    }
}
echo str_repeat("</ul>\n",$previous_dash_count);

我做了几个假设。输入文本总是表现良好且不包含随机性。此外,我不假设UTF-8文本,但你用破折号是安全的。

这是所有血腥荣耀的数组版本:

$stack = array();
$previous_dash_count = 0;
$parent_node = array();
foreach ($text as $line) {
    if (preg_match('/(^\-+)(.*)/', $line, $matches, PREG_OFFSET_CAPTURE)===1) {
        $dash_count = strlen($matches[1][0]);
        $title = $matches[2][0];

        if ($dash_count == $previous_dash_count) {
            $parent_node[] = $title;
        } elseif ($dash_count > $previous_dash_count) {
            for ($push_count = $previous_dash_count; $push_count<$dash_count; $push_count++) {
                array_push($stack, $parent_node); // remember node
                $new_child = array();
                $new_child[] = $title;
                $parent_node[] = $new_child;
                $parent_node = $new_child;
            }
        } else {
            for ($pop_count = $previous_dash_count; $pop_count >$dash_count; $pop_count--) {
                $old_child = $parent_node;
                $parent_node = array_pop($stack);
                $parent_node[] = $old_child;
            }
            $parent_node[] = $title;
        }

        $previous_dash_count = $dash_count;
    }
}
for ($pop_count = $previous_dash_count; $pop_count > 0; $pop_count--) {
    $old_child = $parent_node;
    $parent_node = array_pop($stack);
    $parent_node[] = $old_child;
}

print_r($parent_node);

我们保留一堆数组节点,因此我们在子节点和父节点之间建立了链接。请注意,此代码的结构与直接HTML版本的结构相同。