PHP строка во вложенный / многомерный массив - PullRequest
3 голосов
/ 30 декабря 2011

У меня есть пример строки php:

$ string = "@ [item_1] [door] @ [mozart] [grass] = yes @ [mozart] [green] = no @ [mozart] [человек] @ [синий] [фильм] = да @ [item_1] [бит] = да @ [item_1] [музыка] = нет ";

теперь $ строка переименована простовид:

  1. @ [item_1] [дверь]
    • @ [mozart] [трава] = да
    • @ [Моцарт] [зеленый] = нет
    • @ [моцарт] [человек]

      • @ [синий] [фильм] = да

    • @ [item_1] [beat] = да
    • @ [item_1] [music] = нет

Я хочу знать, как я могу получить эту строку (или другую строку, соответствующую этому стилю) и преобразовать в массив, который выглядит следующим образом:

Array
(
    [item_1] => Array
        (
            [door] => Array
                (
                    [mozart] => Array
                        (
                            [grass] => yes
                            [green] => no
                            [human] => Array
                                (
                                    [blue] => Array
                                        (
                                            [movie] => yes
                                        )
                                )
                        )
                )
            [beat] => yes
            [music] => no
        )
)

Что я пробовал

Я пытался использовать рекурсивную функцию для создания вложенного массива, но у меня не было доступа к указателю массива (в глубоких уровнях) в рекурсивных функциях ... не знаю почему.возможно это неправильный патч ответ.спасибо,

1 Ответ

3 голосов
/ 04 января 2012

ОК, я надеюсь, что вам все еще это нужно, потому что я потратил больше времени, чем мне хотелось бы, чтобы администратор понял это правильно:)

По сути, мой подход состоял в том, чтобы сначала манипулировать строкой в ​​формате [set] [of] [keys] = значение, а затем переберите последовательность ключей и сравните их с последним набором ключей, чтобы создать правильную иерархию ключей.Я использовал eval, потому что это проще, но вы можете написать функцию замены, если не можете увидеть эту функцию в своем коде:

//FIRST WE GET THE STRING INTO EASIER TO WORK WITH CHUNKS
$original_string = "@[item_1][door] @[mozart][grass] = yes @[mozart][green] = no @[mozart][human] @[blue][movie]=yes @[item_1][beat] = yes @[item_1][music] = no ";
$cleaned_string = str_replace('] @[','][',$original_string);
/* This results in clusters of keys that equal a value:
@[item_1][door][mozart][grass] = yes @[mozart][green] = no @[mozart][human][blue][movie]=yes @[item_1][beat] = yes @[item_1][music] = no 

OR (with line breaks for clarity):

@[item_1][door][mozart][grass] = yes 
@[mozart][green] = no 
@[mozart][human][blue][movie]=yes 
@[item_1][beat] = yes 
@[item_1][music] = no */

//break it up into an array:
$elements = explode('@',$cleaned_string);

//create a variable to compare the last string to
$last_keys = "";
//and another that will serve as our final array
$array_of_arrays = array();
//now loop through each [item_1][door][mozart][grass] = yes,[mozart][green] = no, etc
foreach($elements as $element){
    if ($element==""){continue;} //skip the first empty item

    //break the string into [0] = group of keys and [1] the value that terminates the string 
    //so [item_1][door][mozart][grass] = yes BECOMES [item_1][door][mozart][grass], AND yes
    $pieces = explode('=',str_replace(array('[',']'),array("['","']"),trim($element))); 
    //now compare this set of keys to the last set of keys, and if they overlap merge them into a single key string
    $clean_keys = combine_key_strings($pieces[0],$last_keys);
    //set the new key string the value for the next comparison
    $last_keys = $clean_keys;
    //and (ugly, I know) we use an eval to convert "[item_1][door][mozart][grass]='yes'" into a properly keyed array
    eval("\$array_of_arrays".$clean_keys." = '".trim($pieces[1])."';");
}

//now dump the contents
print_r($array_of_arrays);


//THIS FUNCTION COMPA
function combine_key_strings($new,$old){
    //get the key that starts the newer string
    $new_keys = explode('][',$new);
    $first_key = $new_keys[0].']';

    //see if it appears in the last string
    $last_occurance = strrpos ($old,$first_key);
    //if so, merge the two strings to create the full array keystring
    if (is_int($last_occurance)){
        return substr($old,0,$last_occurance).$new;
    }
    return $new;
}

Это должно выплевывать ваш правильно вложенный массив:

Array
(
    [item_1] => Array
        (
            [door] => Array
                (
                    [mozart] => Array
                        (
                            [grass] => yes
                            [green] => no
                            [human] => Array
                                (
                                    [blue] => Array
                                        (
                                            [movie] => yes
                                        )

                                )

                        )

                )

            [beat] => yes
            [music] => no
        )

)

Спокойной ночи!

...