从平面文本生成多维数组

时间:2013-01-15 13:56:36

标签: php arrays preg-match preg-match-all

我有一个文本字段,我将菜单导航为平面文本 - 就像这样:

Company
- Apple
-- Inbound
-- Outbound
--- Delete
- Microsoft
-- Inbound
Invoices
- Customers
-- Apple
--- January

等等。现在我想创建一个多维数组。该数组应如下所示:

Array
(
    [Company] => Array
        (
            [Apple] => Array
                (
                    [Inbound] => '',
                    [Outbound] => Array
                        (
                           [Delete] => ''
                        )
                )

但我不知道该怎么做。谁能给我一个提示?

1 个答案:

答案 0 :(得分:0)

@Rocket Hazmat是正确的。破折号表示每个项目的深度。试试这个:

<?php

function parse_line($line)
{
    $split = explode(" ", $line);
    $result = count($split) == 1 ? array(0, $split[0]) : array(strlen($split[0]), $split[1]);
    return $result;
}

function find_parent($item, $lines)
{
    $dashes = str_pad("", $item[0], '-');
    $orig_line = $item[0] ? $dashes.' '.$item[1] : $item[1];
    $key_of_orig_line = array_search($orig_line, $lines);
    $depth = $item[0];
    for($i = $key_of_orig_line-1; $i > -1; $i--)
    {
        $current_item = parse_line($lines[$i]);
        $current_depth = $current_item[0];
        if($current_depth < $depth)
        {
            return $current_item;
        }
    }
    return array(null, null);
}

function get_trail($item, $lines)
{
    $trail = array();
    $parent = find_parent($item, $lines);
    $trail[] = $parent[1];
    while($parent[1] != null)
    {
        $parent = find_parent($parent, $lines);
        $trail[] = $parent[1];
    }
    return array_reverse($trail);
}

function add_to_menu($item, $trail, $menu)
{
    $cursor = &$menu;
    for($i = 0; $i < count($trail); $i++)
    {
        if($trail[$i] == null) continue;
        $trail[$i] = substr($trail[$i], 0, -3);
        if(!array_key_exists($trail[$i], $cursor) || $cursor[$trail[$i]] == '') $cursor[$trail[$i]] = array();
        $cursor = &$cursor[$trail[$i]];
    }
    $cursor = array_merge($cursor, array(substr($item[1], 0, -3) => ''));
    return $menu;
}

function assign_ids($lines)
{
    $new = array();
    $id_counter = 100;
    foreach($lines as $line)
    {
        $new[] = $line.$id_counter;
        $id_counter++;
    }
    return $new;
}

function p($s) { echo '<pre>'; print_r($s); echo '</pre>'; }

$input = "Company
- Apple
-- Inbound
-- Outbound
--- Delete
- Microsoft
-- Inbound
Invoices
- Customers
-- Apple
--- January";

$menu = array();

$lines = explode("\n", $input);
$lines = array_map("trim", $lines);
$lines = assign_ids($lines);

foreach($lines as $line)
{
    $item = parse_line($line);
    $trail = get_trail($item, $lines);
    $menu = add_to_menu($item, $trail, $menu);
}

p($menu);

?>