дерево массив

Тема в разделе "PHP", создана пользователем SergXP, 17 дек 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. SergXP

    SergXP Постоялец

    Регистр.:
    8 мар 2008
    Сообщения:
    66
    Симпатии:
    11
    Всем добрый день! =)

    Проблема такая.
    В БД хранится массив вида:


    PHP:
    Array
    (
        [
    0] => 1              
        
    [1] => 1_3
        
    [2] => 1_7
        
    [3] => 7_3     
        
    [4] => 7_3_5   
        
    [5] => 7_3_6   
        
    [6] => 7_3_9
        
    [7] => 8_2_4   
    )
    необходимо отбросить элементы и получить вот такой массив:
    PHP:
    Array
    (
        [
    0] => 1
        
    [1] => 7              
        
    [2] => 7_3      
        
    [3] => 8
        
    [4] => 8_2  
        
    [2] => 8_2_4 
    )
    Кол-во элементов не фиксировано, а также уровни могут быть
    1, 1_2, 1_2_3, 1_2_3_4, 1_2_3_4_5 и тд.


    Есть идеи? Ума не приложу пока, как это реализовать, вынужден обратиться за помощью.
     
  2. chang

    chang

    Регистр.:
    20 ноя 2009
    Сообщения:
    364
    Симпатии:
    117
    может не стоит в бд хранить данные в формате "строковый-масив": "8_2_4" , " 7_3_5 "...
    а вместо этого создать еще 1 табличку в соотношении 1 ко многим для связи данных.
    т.е. для записи [4] => 7_3_5 во второй таблице будет 3 записи

    Код:
    id_с_первой_таблицы,  число
    4                      7
    4                      3
    4                      5
    
    при таком хранении данных выборку можно реализовать средствами самой СУБД, а не доставать из БД "все" и играться с ним перебирая /сортируя/фильтруя ... - работать просто дольше будет

    ----
    если такое не подходит то не совсем понятно по какому принципу из 1 массива отсеиваются записи
     
  3. SergXP

    SergXP Постоялец

    Регистр.:
    8 мар 2008
    Сообщения:
    66
    Симпатии:
    11
    Боюсь задействовать новые поля и таблицы БД не получится.
    Имеется дерево чекбоксов.
    Значения которых имеют как раз такой вид:
    Пользователь ставит галочки, и нажимает сохранить.
    В БД записываются эти значения.
    В данном примере выбран самый первый чекбокс, который имеет значение 1.
    Значит все остальные элементы 1_2,1_2_3 и тд.. можно отсеять...
    А если пользователь выберет к примеру элемент
    1_2_3_4_5
    то необходимо создать массив
     
  4. Phrack

    Phrack

    Регистр.:
    3 ноя 2010
    Сообщения:
    264
    Симпатии:
    38
    я не совсем понял что нужно, но насколько я понимаю, сейчас стоит проблема формировать
    PHP:
    1,
    1_2,
    1_2_3,
    1_2_3_4,
    1_2_3_4_5 
    такой массив из выбранного номера чекбокса
    PHP:
    1_2_3_4_5
    ?

    могу предложить такое решение. Допустим известно, что выбран чекбокс с 1_2_3_4_5.
    PHP:
    $numbers explode('_',$checkBoxId);
    while(
    count(numbers>1))
    {
       
    $result[] = implode('_',$numbers);
       
    array_pop($numbers);
    }
    $result[] = '1'//$result = array('1_2_3_4_5','1_2_3_4',..,'1');
    а дальше выборка к базе. Код не тестил, очень рекомендую почитать про nested sets
     
    SergXP нравится это.
  5. SergXP

    SergXP Постоялец

    Регистр.:
    8 мар 2008
    Сообщения:
    66
    Симпатии:
    11
  6. CrashX

    CrashX В прошлом XSiteCMS

    Регистр.:
    6 июн 2008
    Сообщения:
    682
    Симпатии:
    112
    есть выход для 1 поля
    это
    1 серилизация данных serialize($val);unserialize($val);
    2 поле типа Bit, данный метод используется для мобильных платформ часто
    смещение и бит... позволяет хнаить 8 настроек 8 бит 8 флажков если больше 8 то неподходит...
    как выход получать быстро данные серилизаци, или парсить самому строку... хоть серелизованый вид занимает больше места тк там описывается структура.
     
  7. SergXP

    SergXP Постоялец

    Регистр.:
    8 мар 2008
    Сообщения:
    66
    Симпатии:
    11
    Phrack, вроде удалось сделать это, спасибо!
    XSiteCMS, данные хранятся в serialize().
    Но вот с типом Bit не приходилось работать =(
    И удалить ветки мне не удается.
    Если выбран чекбокс со значением 1
    то все элементы массива начинающие на 1_ нужно отбросить.
    допустим массив такой:
    PHP:
    Array 

        [
    0] => 7_3          // это разбить на 7, 7_3
        
    [1] => 7_3_1        // это отбросить, т.к. выбран уже 7_3  
        
    [2] => 7_3_2        // и это тоже отбросить    
        
    [3] => 7_3_3        // тоже отбрасываем
        
    [4] => 8_2_4        // разбиваем на 8, 8_2, 8_2_4
    )  
    сейчас я получаю массив вида:
    PHP:
    Array 

        [
    0] => 7
        
    [1] => 7_3          
        
    [2] => 7_3_1           // вот это отбросить
        
    [3] => 7_3_2           // вот это отбросить
        
    [4] => 7_3_3           // вот это отбросить
        
    [5] => 8
        
    [6] => 8_2
        
    [7] => 8_2_4        
    )  
    голова кругом, две недели бьюсь с этими массивами блин =(

    КОД:
    PHP:

            $result 
    = array();
            foreach (
    $regions as $e) {
                if (
    substr_count($e'_') <= 0) {
                    
    $result[] = $e
                } else {

                    
    $numbers explode('_'$e);
     
                    if (
    array_search($e,$resulttrue) === FALSE) {
                    while (
    count($numbers) > 1) {
                        if (
    array_search(implode('_'$numbers),$resulttrue) === FALSE) {
                            
    $result[] = implode('_'$numbers);
                        }
                        
    array_pop($numbers);
                    }
                    if (
    array_search($numbers[0],$resulttrue) === FALSE)
                    
    $result[] = $numbers[0]; //$result = array('1_2_3_4_5','1_2_3_4',..,'1');


                    
    }
                }
            }
    sort($result);
     
  8. Phrack

    Phrack

    Регистр.:
    3 ноя 2010
    Сообщения:
    264
    Симпатии:
    38
    PHP:
    <?
    $arr = Array 
    (
    '7_3',          // это разбить на 7, 7_3
    '7_3_1',       // это отбросить, т.к. выбран уже 7_3  
    '7_3_2',       // и это тоже отбросить    
    '7_3_3',        // тоже отбрасываем
    '8_2_4',        // разбиваем на 8, 8_2, 8_2_4
    );


    while(
    sizeof($arr)>0)
    {
        
    $prepattern array_shift($arr);
        
    $result[] = $prepattern;
        
    $pattern '/'.$prepattern.'_(.)*/';
        
    $size sizeof($arr);
        for (
    $j=0;$j<$size;$j++)
        {
            if (
    preg_match($pattern,$arr[$j]))
            {
                  unset(
    $arr[$j]);
            }
                
        }
    }

    var_dump($result); // array(2) { [0]=> string(3) "7_3" [1]=> string(5) "8_2_4" } 
    ?>
    так надо?
     
    SergXP нравится это.
  9. Kloster

    Kloster

    Регистр.:
    22 июн 2009
    Сообщения:
    216
    Симпатии:
    12
    а не проще в именах чекбоксов сразу использовать многомерный массив?
    <input type=checkbox name="ch[1]">
    <input type=checkbox name="ch[1][2]">
    <input type=checkbox name="ch[1][2][3]">
    <input type=checkbox name="ch[1][2][4]">
    сразу получишь массив и делай с ни что хошь.
     
Статус темы:
Закрыта.