Recursion Fail..

C++ JAVA
Post Reply
User avatar
xlebabarov
Нов
Нов
Posts: 184
Joined: Tue Nov 10, 2009 6:24 am

Recursion Fail..

Post by xlebabarov » Thu Sep 06, 2018 7:33 pm

Здравейте, боря се с проблема за рекрусията:

[sql]-- phpMyAdmin SQL Dump
-- version 4.8.2
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Sep 06, 2018 at 09:20 PM
-- Server version: 10.1.34-MariaDB
-- PHP Version: 7.2.7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES cp1251 */;

--
-- Database: `blank_website`
--

-- --------------------------------------------------------

--
-- Table structure for table `user_product_categories`
--

CREATE TABLE `user_product_categories` (
`id` int(11) NOT NULL,
`name` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL,
`main` int(11) NOT NULL,
`level` int(11) NOT NULL,
`orders` int(11) NOT NULL,
`user_added` int(11) NOT NULL,
`user_edited` int(11) NOT NULL,
`time_added` int(11) NOT NULL,
`time_edited` int(11) NOT NULL,
`user_ip` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;

--
-- Dumping data for table `user_product_categories`
--

INSERT INTO `user_product_categories` (`id`, `name`, `main`, `level`, `orders`, `user_added`, `user_edited`, `time_added`, `time_edited`, `user_ip`) VALUES
(1, 'Electronics', 0, 0, 1, 1, 0, 1533326058, 0, '1'),
(2, 'Computers & Tablets', 1, 1, 1, 1, 0, 1533326058, 0, '1'),
(3, 'Cameras & Photos', 1, 1, 2, 1, 0, 1533326058, 0, '1'),
(4, 'TV Audio & Surveillance', 1, 1, 3, 1, 0, 1533326058, 0, '1'),
(5, 'Video Games & Consoles', 1, 1, 4, 1, 0, 1533326058, 0, '1'),
(6, 'Cell phones & Accessories', 1, 1, 5, 1, 0, 1533326058, 0, '1'),
(7, 'Fashion', 0, 0, 2, 1, 0, 1533326058, 0, '1'),
(8, 'Home & Garden', 0, 0, 3, 1, 0, 1533326058, 0, '1'),
(9, 'Shop Cellphones & Accessories', 6, 2, 1, 1, 0, 1533326058, 0, '1'),
(10, 'Cellphones & Smartphones', 6, 2, 2, 1, 0, 1533326058, 0, '1');

-- --------------------------------------------------------

--
-- Table structure for table `user_product_categories_lang`
--

CREATE TABLE `user_product_categories_lang` (
`id` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
`lang_id` int(11) NOT NULL,
`name` varchar(225) COLLATE cp1251_bulgarian_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;

--
-- Dumping data for table `user_product_categories_lang`
--

INSERT INTO `user_product_categories_lang` (`id`, `cat_id`, `lang_id`, `name`) VALUES
(1, 1, 1, 'Електроника'),
(2, 1, 2, 'Electronics'),
(3, 2, 2, 'Computers & Tablets'),
(4, 3, 2, 'Cameras & Photos'),
(5, 4, 2, 'TV Audio & Surveillance'),
(6, 5, 2, 'Video Games & Consoles'),
(7, 6, 2, 'Cell phones & Accessories'),
(8, 2, 1, 'Компютри и таблети'),
(9, 3, 1, 'Камери и снимки'),
(10, 4, 1, 'ТВ Аудио и Охранителна техника'),
(11, 5, 1, 'Видео игри и конзоли'),
(12, 6, 1, 'Мобилни телефони & Аксесоари'),
(13, 7, 2, 'Fashion'),
(14, 8, 2, 'Home & Garden'),
(15, 7, 1, 'Мода'),
(16, 8, 1, 'Дом & Градина'),
(17, 9, 2, 'Shop Cellphones & Accessories'),
(18, 10, 2, 'Cellphones & Smartphones'),
(19, 9, 1, 'Клетъчни телефони & Аксесоари'),
(20, 10, 1, 'Клетъчни телефони & Смартфони');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `user_product_categories`
--
ALTER TABLE `user_product_categories`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `user_product_categories_lang`
--
ALTER TABLE `user_product_categories_lang`
ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `user_product_categories`
--
ALTER TABLE `user_product_categories`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;

--
-- AUTO_INCREMENT for table `user_product_categories_lang`
--
ALTER TABLE `user_product_categories_lang`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=21;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;[/sql]

[php]$url = 'http://localhost/starniko/';
$homec = '\\';
$home = 'E:\xampp\htdocs\starniko'.$homec;

$c = array(0 => $url,
1 => $homec,
2 => $home);

// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
}
mysqli_query($conn, "SET CHARACTER SET utf8");

[/php]

А в случая Glang e това:

[php]<?php
$glang = array(
//'' => '',
'does_not_match_mysql_add' => 'Посочените стойности не съвпадат. Моля, уравновесете.',
'mysql_add_table_not_null' => 'Посочените стойности в таблицата за добавяне не могат да са празни. Моля, изберете стойност.',
'mysql_add_value_not_array' => 'Стойностите, value0 or value1 не са масив. Моля, предоставете масив.',
'mysql_select_table_not_null' => 'Посочените стойности в таблицата за селектиране не могат да са празни. Моля, изберете стойност.',
'mysql_select_what_not_null' => 'Стойността какво не може да е нула. Моля, изберете стойности.',
'mysql_select_is_not_array_where' => 'Стойността where не е масив. Моля, изберете масив.',
'mysql_select_is_not_array_where0' => 'Стойността where0 не е масив. Моля, изберете масив.',
'mysql_select_is_not_array_where1' => 'Стойността where1 не е масив. Моля, изберете масив.',
'mysql_select_is_not_the_same_where' => 'Стойността where0 и where1 не са равни. Моля, уравновесете.',
'mysql_update_table_not_null' => 'Таблицата в стойности за ъпдейт не може да бъде празна. Моля, изберете стойност.',
'mysql_update_update_not_null' => 'Ъпдейта в стойности за ъпдейт не може да бъде празен. Моля, изберете стойност.',
'mysql_update_update_not_array'> 'Ъпдейта в стойности за ъпдейт не може да не бъде масив. Моля, изберете стойност.',
'mysql_update_update_not_equal' => 'Ъпдейта или където в стойности за ъпдейт не може да бъдат празни или неравни. Моля, изберете стойност.',
'mysql_update_where_not_array' => 'Където в стойности за ъпдейт не може да не бъдат масив. Моля, изберете стойност.',
'Close_menu' => 'Затвори менюта',
'log_out' => 'Изход',
'' => '',
'' => '',// BB Code
'quoted' => 'Цитат',
'said' => 'каза',
'Image' => 'Изображение',
//Profile
//'' => '',
'Username' => 'Потребителско име',
'Password' => 'Парола',
'Email' => 'E-mail',
'Level' => 'Ниво',
'Country' => 'Държава',
'Countries' => 'Държави',
'Language' => 'Език',
'Credits' => 'Кредити',
'Gender' => 'Пол',
//Products
'Name' => 'Име',
'Store_id' => 'Име на магазин',
'Cat_id' => 'Категория',
'User_ip' => 'IP на потребител',
'Description' => 'Описание',
'Images' => 'Изображения',
'' => '',
'Time_added' => 'Добавено на',
//Register
'Check' => 'Провери',
'Change' => 'Промени',
'username_free' => 'Потребителското име е свободно.',
'username_not_free' => 'Потребителското име е заето.',
'select_an_option' => 'Моля изберете',
'Register' => 'Регистрация',
'email_not_free' => 'E-mail-ът вече се използва',
'email_free' => 'E-mail-ът е свободен',
'Lang' => 'Език',
'Address' => 'Адрес',
'Mobile_phone' => 'Мобилен телефон (код/телефон)',
'could_not_be_empty' => ' не може да бъде празен.',
'username_cannot_contain_extra_characters' => 'Потребителското име не може да съдържа допълнителни знаци. Може да съдържа само букви от аА до zZ и _.',
'not_valid' => ' е невалидно.',
'username_not_less' => 'Потребителското име трябва да бъде между 4 и 12 символа',
'password_not_less' => 'Паролата трябва да бъде между 4 и 12 символа',
'country_not_less' => 'Държавата трябва да е под или 10 символа',
'gender_not_less' => 'Полът трябва да е под или 10 символа',
'language_not_less' => 'Езикът трябва да е под или 10 символа',
'address_not_less' => 'Адресът трябва да е под или 10 символа',
'phone_code_not_less' => 'Телефонен код трябва да е под или 10 символа',
'phone_num_not_less' => 'Телефонен номер трябва да е под или 20 символа',
'registration_success' => 'Регистрацията успешна!',
// Add Product
'Product_name' => 'Име на продукта',
'Pictures' => 'Снимки',
'Categorie' => 'Категория',
'Send' => 'Изпрати',
'Submit' => 'Изпращане',

'' => ''
);
?>[/php]

Просто за изпълненнието на файла за да ме разберете давам и функцията си mysql_select която е добро мое изобретение, служещо ми вярно като идеята на функцията е да избере от
  • table - Името на селектираната таблица
    where - WHERE заявката на таблицата array('id') = array(1) под кода $where = array(array(), array())
    order - Реда на селектирането да речем array('id')=array('ASC') под кода $order = array(array(), array())
[php]function mysql_select($table, $what = array('*'), $where = array(array(), array()), $order = array(array(), array())){
global $conn;
global $glang;


$sql = 'SELECT ';
if(!$table){
die($glang['mysql_select_table_not_null']);
}
switch(count($what)){
case 0:
die($glang['mysql_select_what_not_null']);
break;
case 1:
if($what[0]=='*'){
$sql.= '*';
}else{
$sql.= '`'.$what[0].'`'; }
break;
}
if((count($what)>=2)&&(count($what)!=1)){
for($i=0;$i<=count($what)-1;$i++){
$sql.='`'.$what[$i].'`';
if($i!=count($what)-1){
$sql.=', ';
}else{
$sql.=' ';
}
}

}

$sql.= 'FROM `'.$table.'` ';

if(!is_array($order)){die('Order must be array. Please, select value.');}
if(!is_array($order[0])){die('Order0 must be array. Please, select value.');}
if(!is_array($order[1])){die('Order1 must be array. Please, select value.');}
if(count($order[0])!=count($order[1])){die('Order count must be equal. Please, select value.');}

if((count($where[0])==0)&&(count($where[1])==0)){
if(count($order[0])>=1){
$sql .= 'ORDER BY ';
for($i=0;$i<=count($order[0])-1;$i++){
$sql.='`'.$order[0][$i].'` '.$order[1][$i];
if($i!=count($order[0])-1){
$sql.=', ';
}
}
}


$result = mysqli_query($conn, $sql);
$rezult = array();
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
array_push($rezult, $row);
}
return $rezult;
} else {
return false;
}

}else{

if(!is_array($where)){ die($glang['mysql_select_is_not_array_where']);}
if(!is_array($where[0])){ die($glang['mysql_select_is_not_array_where0']);}
if(!is_array($where[1])){ die($glang['mysql_select_is_not_array_where1']);}
if(count($where[0])!=count($where[1])){ die($glang['mysql_select_is_not_the_same_where']);}
$sql.='WHERE ';
for($i=0;$i<=count($where[0])-1;$i++){
if($i!=count($where[0])-1){
$sql.= '`'.$where[0][$i].'` = \''.$where[1][$i].'\' AND ';
}else{
$sql.= '`'.$where[0][$i].'` = \''.$where[1][$i].'\'';

}
}
if(count($order[0])>=1){
$sql .= 'ORDER BY ';
for($i=0;$i<=count($order[0])-1;$i++){
$sql.='`'.$order[0][$i].'` '.$order[1][$i];
if($i!=count($order[0])-1){
$sql.=', ';
}
}
}

$result = mysqli_query($conn, $sql);
$rezult = array();
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
array_push($rezult, $row);
}
return $rezult;
} else {
return false;
}

}



}
[/php]

Рекрусията съм я включил ей тук но за съжаление скрипта не се изпълнява:

[php]function has_children($cat, $id){
if(!$cat){die('Please, select cat.');}
if(!$id){die('Please, select id.');}
if(!is_numeric($id)){die('Please, select numeric values.');}


for($i=0;$i<=count($cat)-1;$i++){
foreach($cat[$i] as $key => $val){
if($key=='main'){
if($val==$id){return true;}
}
}
}
}

function make_menu_rows($array = array(), $level = 0){
$rez = mysql_select('user_product_categories', array('id', 'name', 'main', 'level', 'orders'), array(array('level'), array($level)), array(array('orders'), array('ASC')));
$rez1 = mysql_select('user_product_categories', array('*'));
$array1 = array();

foreach($rez as $var){
$array_key = array_pop(array_keys($array));
if(isset($array_key)){$array_var = $array_key+1;}else{$array_var = 0;}
$array[$array_var] = array('Main' => $var);


if(has_children($rez1, $var['id'])){
$rez2 = mysql_select('user_product_categories', array('id', 'name', 'main', 'level', 'orders'), array(array('main'), array($var['id'])), array(array('orders'), array('ASC')));
foreach($rez2 as $var1){
if(has_children($rez1, $var1['id'])){
array_push($array[$array_var], array('Sub' => $var1));
make_menu_rows($array, $var1['level']);
}else{
array_push($array[$array_var], array('Sub' => $var1));
}
}
}else{
}
}
return $array;
}


$make = make_menu_rows();
print_r($make);[/php]

резултатът е:

Code: Select all

Array
&#40;
    &#91;0&#93; => Array
        &#40;
            &#91;Main&#93; => Array
                &#40;
                    &#91;id&#93; => 1
                    &#91;name&#93; => Electronics
                    &#91;main&#93; => 0
                    &#91;level&#93; => 0
                    &#91;orders&#93; => 1
                &#41;

            &#91;0&#93; => Array
                &#40;
                    &#91;Sub&#93; => Array
                        &#40;
                            &#91;id&#93; => 2
                            &#91;name&#93; => Computers & Tablets
                            &#91;main&#93; => 1
                            &#91;level&#93; => 1
                            &#91;orders&#93; => 1
                        &#41;

                &#41;

            &#91;1&#93; => Array
                &#40;
                    &#91;Sub&#93; => Array
                        &#40;
                            &#91;id&#93; => 3
                            &#91;name&#93; => Cameras & Photos
                            &#91;main&#93; => 1
                            &#91;level&#93; => 1
                            &#91;orders&#93; => 2
                        &#41;

                &#41;

            &#91;2&#93; => Array
                &#40;
                    &#91;Sub&#93; => Array
                        &#40;
                            &#91;id&#93; => 4
                            &#91;name&#93; => TV Audio & Surveillance
                            &#91;main&#93; => 1
                            &#91;level&#93; => 1
                            &#91;orders&#93; => 3
                        &#41;

                &#41;

            &#91;3&#93; => Array
                &#40;
                    &#91;Sub&#93; => Array
                        &#40;
                            &#91;id&#93; => 5
                            &#91;name&#93; => Video Games & Consoles
                            &#91;main&#93; => 1
                            &#91;level&#93; => 1
                            &#91;orders&#93; => 4
                        &#41;

                &#41;

            &#91;4&#93; => Array
                &#40;
                    &#91;Sub&#93; => Array
                        &#40;
                            &#91;id&#93; => 6
                            &#91;name&#93; => Cell phones & Accessories
                            &#91;main&#93; => 1
                            &#91;level&#93; => 1
                            &#91;orders&#93; => 5
                        &#41;

                &#41;

        &#41;

    &#91;1&#93; => Array
        &#40;
            &#91;Main&#93; => Array
                &#40;
                    &#91;id&#93; => 7
                    &#91;name&#93; => Fashion
                    &#91;main&#93; => 0
                    &#91;level&#93; => 0
                    &#91;orders&#93; => 2
                &#41;

        &#41;

    &#91;2&#93; => Array
        &#40;
            &#91;Main&#93; => Array
                &#40;
                    &#91;id&#93; => 8
                    &#91;name&#93; => Home & Garden
                    &#91;main&#93; => 0
                    &#91;level&#93; => 0
                    &#91;orders&#93; => 3
                &#41;

        &#41;

&#41;
Като тук

Code: Select all

            &#91;4&#93; => Array 
                &#40; 
                    &#91;Sub&#93; => Array 
                        &#40; 
                            &#91;id&#93; => 6 
                            &#91;name&#93; => Cell phones & Accessories 
                            &#91;main&#93; => 1 
                            &#91;level&#93; => 1 
                            &#91;orders&#93; => 5 
                        &#41; 

                &#41; 
Би трябвало да се включи рекрусията понеже в таблицата Cell Phones & Accessories е с main 1 и включени 2 подменюта които не излизат ID 9 и 10

Shop Cellphones & Accessories
и
Cellphones & Smartphones
с level 2 и main 6

Ако схващате идеята моля помогнете :?:

raiden
Гуру
Гуру
Posts: 2182
Joined: Fri Dec 08, 2006 8:13 am
Answers: 190
Location: Варна

Post by raiden » Sat Sep 08, 2018 1:10 am

Ако използваш MySQL 8 можеш да си направиш рекурсията в заявката:
https://www.db-fiddle.com/f/se4UTULGTUbVT6Lmwy33x5/1

User avatar
xlebabarov
Нов
Нов
Posts: 184
Joined: Tue Nov 10, 2009 6:24 am

Post by xlebabarov » Wed Sep 12, 2018 11:46 am

raiden wrote:Ако използваш MySQL 8 можеш да си направиш рекурсията в заявката:
https://www.db-fiddle.com/f/se4UTULGTUbVT6Lmwy33x5/1
За съжаление не ползвам 8 а някъкви идеи защо не работи кода?
Гошо пича ;) Понякога питам въпросчета с повишена трудност, но какво да се прави :)

raiden
Гуру
Гуру
Posts: 2182
Joined: Fri Dec 08, 2006 8:13 am
Answers: 190
Location: Варна

Post by raiden » Wed Sep 12, 2018 7:43 pm

Функцията ти вика сама себе си, но това извикване не променя нищо в резултата. Трябва да имаш нещо от рода на

Code: Select all

$array = make_menu_rows&#40;$array, $var1&#91;'level'&#93;&#41;;
или директно да правиш

Code: Select all

return make_menu_rows&#40;$array, $var1&#91;'level'&#93;&#41;;
за да работиш при всяко следващо извикване с резултата от предишното. Иначе функцията не е рекурсивна. Предвид че имаш нивото на всяка категория в йерархията, рекурсията не е наложителна и можеш да минеш с нещо такова:
[php]<?php
$array = [
0 => ['id' => 1, 'name' => 'Electronics2', 'main' => 0, 'level' => 0],
1 => ['id' => 2, 'name' => 'Electronics1', 'main' => 0, 'level' => 0],
2 => ['id' => 3, 'name' => 'Electronics11', 'main' => 2, 'level' => 1],
3 => ['id' => 4, 'name' => 'Electronics12', 'main' => 3, 'level' => 2]
];

function nestSubs($array) {
$result = array_reduce(
$array,
function ($result, $i) {
$result[$i['level']][$i['id']] = $i;
return $result;
},
[]
);
$maxLevel = max(array_keys($result));
for ($i = $maxLevel; $i > 0; $i--) {
foreach($result[$i] as $sub) {
$result[$i - 1][$sub['main']]['subs'][$sub['id']] = $sub;
}
unset($result[$i]);
}

return $result[0];
}

print_r(nestSubs($array));[/php]

Post Reply