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

Статус
В этой теме нельзя размещать новые ответы.

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 и тд.


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

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

----
если такое не подходит то не совсем понятно по какому принципу из 1 массива отсеиваются записи
 
Боюсь задействовать новые поля и таблицы БД не получится.
Имеется дерево чекбоксов.
Значения которых имеют как раз такой вид:
1,
1_2,
1_2_3,
1_2_3_4,
1_2_3_4_5
Пользователь ставит галочки, и нажимает сохранить.
В БД записываются эти значения.
В данном примере выбран самый первый чекбокс, который имеет значение 1.
Значит все остальные элементы 1_2,1_2_3 и тд.. можно отсеять...
А если пользователь выберет к примеру элемент
1_2_3_4_5
то необходимо создать массив
1
1_2
1_2_3
1_2_3_4
1_2_3_4_5
 
я не совсем понял что нужно, но насколько я понимаю, сейчас стоит проблема формировать
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
 
Хорошо, сейчас попробую ваш алгоритм =)

Да, как раз к ним и обращаюсь:
Для просмотра ссылки Войди или Зарегистрируйся
 
есть выход для 1 поля
это
1 серилизация данных serialize($val);unserialize($val);
2 поле типа Bit, данный метод используется для мобильных платформ часто
смещение и бит... позволяет хнаить 8 настроек 8 бит 8 флажков если больше 8 то неподходит...
как выход получать быстро данные серилизаци, или парсить самому строку... хоть серелизованый вид занимает больше места тк там описывается структура.
 
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,$result, true) === FALSE) {
                while (count($numbers) > 1) {
                    if (array_search(implode('_', $numbers),$result, true) === FALSE) {
                        $result[] = implode('_', $numbers);
                    }
                    array_pop($numbers);
                }
                if (array_search($numbers[0],$result, true) === FALSE)
                $result[] = $numbers[0]; //$result = array('1_2_3_4_5','1_2_3_4',..,'1');


                }
            }
        }
sort($result);
 
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" } 
?>

так надо?
 
а не проще в именах чекбоксов сразу использовать многомерный массив?
<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]">
сразу получишь массив и делай с ни что хошь.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху