Murolike
Интересующийся
Offline
|
|
« : 29-06-2012 22:31 » |
|
Здравствуйте помоги с такой проблемой: Необходима организовать, сохранение в древовидном формате меню в массиве php. Примерный вид кода: Символ \t - является Табуляции, а \r\n - перевод строки. $MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nПока\r\n\Система\r\n\tWindows\r\n\t\tXP\r\n\t\t7\r\n"; Чего добился, но все еще с ошибкой. <?php $MenuName=$_POST['mName']; // Название меню $MenuCode=$_POST['mCode']; // Код меню $MenuName="Temp"; // Для тестирование : Название $MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nпока\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nсистема\r\n\t2\r\n\t3\r\nрабочий"; // Код меню передающийся на сервер. // Класс меню class Menu{ var $Name; // Название var $Code; // Код var $LengthCode; // Длина кода var $TreeMenu; // Массив для сохранения пунктов ввиде древа var $SplitCode; // Разрека элементов на строчки var $Error; // Переменная для сохранения ошибок var $CopySplitCode; /* Инициализация массива */ function Menu($MenuName,$MenuCode) { $this->Name=$MenuName; $this->Code=$MenuCode; $this->LengthCode=strlen($MenuName); $this->TreeMenu=array(); $this->SplitCode=preg_split("/\n/",$this->Code); // $i=$k=0; $this->TreeMenu=$this->TreeCreate($this->TreeMenu,0); echo "aa"; } /* Функция для построения дерева */ function TreeCreate($TreeArray) { $i=$k=0; foreach ($this->SplitCode as $key => $value) { if($this->CheckElementOnTab($value)==true)// Здесь уже не правильно и это я знаю. { $TreeArray[$i][$k+1]=array(); $this->SplitCode[$key]="имя".$key." "; $this->TreeCreate(&$TreeArray[$i][$k+1]); $i++; } else { $TreeArray[$i][$k]=$value; unset($this->SplitCode[$key]); } } return $TreeArray; } function CheckElementOnTab($value) { for($i=0;$i<strlen($value);$i++) { if($value[$i]=="\t") { return true; } } return false; } } $Object=new Menu($MenuName,$MenuCode); ?> Я понимаю, что для реализации необходима рекурсия, чтобы собрать все в одно, но у меня проблемы остаются с выходом из этой рекурсии, система должна записывать в [$i][0] = Элементы Родителя, а в [$i][1]=array(); Хранятся все дети этого элемента.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #1 : 30-06-2012 15:14 » |
|
объясни какое соответствие между
$this->TreeMenu=$this->TreeCreate($this->TreeMenu,0); и function TreeCreate($TreeArray)
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #2 : 30-06-2012 17:55 » |
|
аа, да 0 можно убрать, с ним и без него тоже работает. 0 использовал для изменения ключа $key в цикле.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #3 : 01-07-2012 09:09 » |
|
Я так и не понял, а что надо-то? $MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nпока\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nсистема\r\n\t2\r\n\t3\r\nрабочий"; Вроде уже имеет древовидный вид
$this->SplitCode=preg_split("/\n/",$this->Code); - а почему именно так, ведь "разделителем" является \r\n. Впрочем. это сути не меняет. Это вопрос второстепенный.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #4 : 02-07-2012 14:42 » |
|
Есть код который вы процитировали, который отправил пользователь, теперь его необходимо превратить в массив вложенностей Допустим Массив $TreeArray[$i][$j] - под элементами [$i] понимают ВЕТКИ, или родители кому как проще, в индексе [$j], где $j=0 это есть Имя Родителя или ветки, а [$j] $j=1 есть массив ДЕТЕЙ, других веток. Примером является древовидное меню: Программу откройте блокнот, там есть "файл", " о программе" и другие вещи - это родители, то что внутри них это дети, но если есть еще вложенности, это дети становятся родителями, то есть иными словами уход на 1 уровень ниже и так на несколько уровней ниже пока не закончится все. Насчет разделителя, не важно, но оставил с \r вдруг в проверки понадобится.
|
|
|
Записан
|
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #5 : 02-07-2012 14:52 » |
|
Вот изображение, это то как он должен быть в php после обработки кода, результат работы функции.
|
temp.jpg (44.54 Кб - загружено 1213 раз.)
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #6 : 02-07-2012 17:14 » |
|
Ну... теперь более менее ясно стало (не прошло и 4-х дней)
Основная функция TreeCreate Опиши ее работу, как ты понимаешь как она должна работать Описать словами не кодом. например Взять текущий элемент, проверить ... , если ... то сделать ... , иначе сделать ... Потом берешь свой код и смотришь, а соответствует ли он описанному?
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #7 : 06-07-2012 04:18 » |
|
ммм да, там не то. ладно вот новый код, по сути он все делает правильно, но если у нас идет переход меню от 2 уровень к 1 он пропускает элемент цикл foreach , а если добавлять параметры с указателем на наш массив элементов, то он слишком часто их дописывает. <?php $MenuName="TEMP"; $MenuCode="привет\r\n\tС1\r\n\tС2\r\n\tС3\r\n\t\tС3-1\r\n\t\tС3-2\r\n\t\tС3-3\r\n\tЫЫЫ\r\nСистема\r\nЭксперт"; $StringCode=preg_split("/\n/",$MenuCode); $Level=0; $TreeArray=array(); $TreeArray=SaveCode($TreeArray,$StringCode); echo "gfg"; function SaveCode($TreeArray) { $i=$j=0; global $Level; global $StringCode; foreach($StringCode as $key => $value) { if(TabElement($value)==true) { $CurrentElement=0; $CurrentElement=CountElementTab($value); if($Level==$CurrentElement) // Если текущий уровень совпадает с кол-вом \t { $j++; $TreeArray[$i][$j]=$value; unset($StringCode[$key]); } else { if($Level>$CurrentElement) // Если уровень больше чем элементов \t { $Level--; return $TreeArray; } else { $Temp=$TreeArray[$i][$j]; $TreeArray[$i][$j]=array(); $TreeArray[$i][$j][0]=$Temp; $Level++; $TreeArray[$i][$j][1]=SaveCode($TreeArray[$i][$j][1]); } } } else { $CurrentElement=0; $CurrentElement=CountElementTab($value); if($Level!=$CurrentElement) // пока уровни не совпадут. { $Level--; return $TreeArray; } else { $TreeArray[$i][$j]=$value; unset($StringCode[$key]); $TreeArray[$i][$j+1]=array(); $Level++; $TreeArray[$i][$j+1]=SaveCode($TreeArray[$i][$j+1]); $i++; } } } return $TreeArray; } function TabElement($value) // Проверка на элемент \t { for($i=0;$i<strlen($value);$i++) { if($value[$i]=="\t") { return true; } } return false; } function CountElementTab($value) // Количество элементов \t { $k=0; for($i=0;$i<strlen($value);$i++) { if($value[$i]=="\t") { $k++; } } return $k; } ?> Вот как избавиться,от такой фигни. Скриншот с результатом этой программы.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 06-07-2012 06:13 » |
|
Основная функция TreeCreate Опиши ее работу, как ты понимаешь как она должна работать Описать словами не кодом. например Взять текущий элемент, проверить ... , если ... то сделать ... , иначе сделать ... Потом берешь свой код и смотришь, а соответствует ли он описанному?
ммм да, там не то. ладно вот новый код ...
Murolike, ты в советах не нуждаешься?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #9 : 06-07-2012 09:02 » |
|
вообще-то я так и сделал и вот, что получилось после переноса слов на код. или надо словами? Словами,тогда будет так.: "Берем элемента из списка, проверяем его на присутствие символа \t, если есть, тогда, сверяем совпадает-ли глобальный уровень и количество элементов \t, если совпадает, то записываем их в прямом порядке, если не совпадает, является ли глобальный уровень больше чем количество элементов \t, если условие выполняется тогда, уменьшаем уровень и возвращаемся на 1 шаг выше, если же не выполняется условие, тогда получается, что текущий глобальный уровень меньше, чем количество элементов \t, а значит создаем для предыдущего элемента массив, где 0 это имя родителя, а 1 его дети и тут же вызываем функцию, чтобы определить если у него дети. Если же у элемента нету \t, тогда записываем его в прямом порядке и вызываем функцию еще раз, для проверки на детей. " Примерно так получается.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #10 : 06-07-2012 09:15 » |
|
Здесь даже рекурсия не нужна
$StringCode - содержит массив строк в виде
[0] привет [1]\tС1 [2]\tС2
... уровень вложенности зависит от количества символов табуляции Задача - запомнить верхний уровень
1. Посчитали количество табов 2. Сделали вывод к какому уровню относимся, и на каком уровне были 3. Соответственно заполнили "дерево"
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Murolike
Интересующийся
Offline
|
|
« Ответ #11 : 06-07-2012 11:50 » |
|
ладно, вроде бы понял, попробую набить на коде, сделал кстати с рекурсии, но попробую и этот вариант. Просто получается, что можно сделать двумерный массив где будет 3 столбца: 1 - элемент 2- количество табов 3- родитель?
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #12 : 06-07-2012 12:39 » |
|
Нет...
Прочитал строку - уровень родителя Положил в массив с индексом родителя Прочитал сдедующую строку - посчитал количество табов (количество табов должно быть столько же или на 1 больше) Если табов столько же - увеличил индекс родителя Если табов больше - в массив c родительским индексом добавляем массив наследника Если табов меньше - обнуляем индекс массива наследника и уменьшаем индекс на количество табов Текст для проверки алгоритма. 1 \t \t \t\t \t\t\t 2
Вот что я от тебя хочу. Никакого кода.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
|