Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многомерный массив 
V
    Опции темы
s1lver
Дата 5.5.2014, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Доброго времени суток!

Подскажите, пожалуйста, такой вопрос. Есть массив вида

Код

$arr = array(
    566=>array(
        560=>"text",
        554=>"text"
    ),
    572=>array(
        568=>"text",
        570=>"text"
    ),
...
);


как можно вывести все значения из массива, чтобы получился список типа 

Код

<ul>
<li><ul><li></li></ul>
</li>
<li><ul><li></li></ul>
</li>
...
</ul>


Набросал код, но не могу понять как учесть вложенные значения
Код

foreach ($arr as $key => $value) {
    echo '<li>.$key';
    echo '<ul>';
        for($i = 0; $i < count($value); $i++) 
               echo '<li>'.$value[$i].'</li>';
    echo '</ul></li>' ;
}
echo '</ul>';


Это сообщение отредактировал(а) s1lver - 5.5.2014, 14:23


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 5.5.2014, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Как-то так, наверное
Код

function makeHTML($data) {
    $html = '<ul>';
    foreach ($data as $key => $row) {
        $html .= '<li>';
        $html .= $key;
        $html .= is_array($row) ? makeHTML($row) : ' => ' . $row;
        $html .= '</li>';
    }
    $html .= '</ul>';

    return $html;
}

$arr = array(
    566=>array(
        560=>"text",
        554=>"text"
    ),
    572=>array(
        568=>"text",
        570=>"text"
    ),
);

echo makeHTML($arr);


Можно почитать в гугле или википедии про рекурсию ;)

Это сообщение отредактировал(а) Aliance - 5.5.2014, 14:45
PM MAIL WWW ICQ Skype   Вверх
s1lver
Дата 5.5.2014, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Хм, тут что-то не так. Возможно, я не правильно вопрос поставил. smile 


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
s1lver
Дата 5.5.2014, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



т.е по сути (из прошлого вопроса) получаем из массива 1 значения, на основании которых ищем в массиве 2 совпадения со значениями. Если найдены совпадения, то выводим ключи(в единственном экземпляре).

массив 2
Код

$arr = array(
    "текст"=>111,
    "текст"=>111,
...
); 


Код

<ul>
foreach(array_unique($elementsArray) as $key=>$value){
    
    if($key_i = array_search($value,$arr)){
        echo "<li id=".$value.">".$key_i."</li>";                            }                        }
</ul>


Но, так можно получить только верхний уровень. Второй уровень вложенности можно получить аналогично, только подставив массив 3, в котором хранятся значения второго уровня вложенности(массив 3, в этом случае, аналогичен массиву 2).

А вот как объединить их, чтобы значения полученные в массиве 3, соответствовали массиву 2? smile 

Поэтому, я подумал что стоит объединить два массива для простоты. 

Это сообщение отредактировал(а) s1lver - 5.5.2014, 15:55


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
s1lver
Дата 6.5.2014, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Вот это, практически, то что надо.

Код

<ul><?foreach(array_unique($elementsArray) as $key=>$value){
    //echo var_dump($value);
    if($key_i = array_search($value,$arr)){
        echo "<li id=".$value.">".$key_i;
                                                 }
                if($key_i_ex = array_search($value,$arr_ex)){
            echo "<ul><li id=".$value.">".$key_i_ex."</li></ul></li>";
        }
                                                    }</ul>

Однако, есть проблема. Если есть более одного уровня вложенности, то эти элементы выводятся внизу списка. 

Т.е 
Код

<ul>
<li>
      <ul><li>правильно</li></ul> 
</li>
<li>
      <ul><li>правильно</li></ul>
</li>
<ul><li>не правильно</li></ul>
</ul>


 Подскажите, как быть?smile 

Это сообщение отредактировал(а) s1lver - 6.5.2014, 10:13


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 6.5.2014, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Совершенно не понятно, что нужно, потому что выражаете свои мысли очень сумбурно smile Проще было бы если бы вы еще раз написали пример простого массива (как в первом посте) на вход и полный пример того, что должен скрипт вывести, обработав его (в первом посте вы написали разметку, на ее основании я написал вам скрипт, но в разметке вы пропустили текстовую часть, возможно из-за этого скрипт вам не подошел).
PM MAIL WWW ICQ Skype   Вверх
s1lver
Дата 6.5.2014, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Необходимо вывести список с двумя уровнями вложенности. Т.е, чтобы структура была такая.

Код

<ul>
<li>текст(1 уровень вложенности)
       <ul><li>правильно</li></ul> (2 уровень)
    <ul><li>правильно</li></ul> 
    <ul><li>правильно</li></ul> 
</li>
<li>текст(1 уровень вложенности)
       <ul><li>правильно</li></ul> (2 уровень)
    <ul><li>правильно</li></ul> 
    <ul><li>правильно</li></ul> 
</li>
    ...
</ul>


Есть исходный массив, в котором хранятся id.

Код

5, 6
5, 7
5,6
4, 77
3, 99

id первого и второго уроня могут совпадать



Есть массив 1, в котором в качестве ключей хранятся описания id первого уровня вложенности, а в качестве значений id первого уровня вложенности.
Есть массив 2, в котором в качестве ключей хранятся описания id второго уровня вложенности, а в качестве значений id второго уровня вложенности.


Чтобы вытащить и обработать значения массива, я написал такой код

Код

<ul><?foreach(array_unique($elementsArray) as $key=>$value){
    //echo var_dump($value);
    if($key_i = array_search($value,$arr)){
        echo "<li id=".$value.">".$key_i;
                                                 }
                if($key_i_ex = array_search($value,$arr_ex)){
            echo "<ul><li id=".$value.">".$key_i_ex."</li></ul></li>";
        }
                                                    }</ul>


Сперва, для первого уровня вложенности, получаем  id из исходного массива и подставляем к полученным id описание из массива1. Т.к описание должно быть в единственном экземпляре, то обрезаю повторяющиеся элементы(подозреваю, что где-то тут накосячил).
Потом получаем значения для id второго уровня вложенности. Из всего этого формируется список.

Код

<ul>
<li>текст
      <ul><li>правильно</li></ul> 
</li>
<li>
      <ul><li>правильно</li></ul>
</li>текст
...
<ul><li>не правильно</li></ul>
</ul>


Т.е список формируется отлично только для первых найденных значений. А когда найдено совпадающее значение в первом уровня, оно убирается и остается только второй уровень. Но его надо добавлять в свой первый уровень.



 


Это сообщение отредактировал(а) s1lver - 6.5.2014, 11:01


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 6.5.2014, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Вы очень усложняете. Мне нужно лишь массив (или массивы, их уже оказывается два?) с реальными значениями (как в первом посте) и разметка, которая д.б. сгенерирована на основе этих же значений. А вы приводите пример абстрактной разметки, которую можно интерпритировать по разному.
PM MAIL WWW ICQ Skype   Вверх
s1lver
Дата 6.5.2014, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Исходный массив заполнил тестовыми значениями

Код

array(28) { [0]=> string(3) "501" [1]=> string(3) "499" [2]=> string(4) "test" [3]=> string(0) ""
            [4]=> string(3) "508" [5]=> string(3) "506" [6]=> string(4) "test" [7]=> string(0) ""
            [8]=> string(3) "522" [9]=> string(3) "514" [10]=> string(4) "test" [11]=> string(0) ""
            [12]=> string(3) "566" [13]=> string(3) "558" [14]=> string(0) "" [15]=> string(0) ""
            [16]=> string(3) "117" [17]=> string(3) "128" [18]=> string(0) "" [19]=> string(0) ""
            [20]=> string(3) "572" [21]=> string(3) "568" [22]=> string(0) "" [23]=> string(0) ""
            [24]=> string(3) "508" [25]=> string(3) "504" [26]=> string(0) "" [27]=> string(0) "" }


Массив 1 заполненный тестовыми значениями
Код

$arr = array(
    "Тест1"=>566,
    "Тест2"=>572,
    "Тест3"=>117,
    "Тест4"=>119,
    "Тест5"=>548,
    "Тест6"=>542,
    "Тест7"=>531,
    "Тест8"=>508,
);

Массив 2 заполненный тестовыми значениями
Код

$arr_ex = array(
    "Тест1"=>560,
    "Тест2"=>554,
    "Тест3"=>562,
    "Тест4"=>564,
    "Тест5"=>558,
    "Тест6"=>556,
    "Тест7"=>552,
    "Тест8"=>550
}


Приведенный, в прошлом посте код, реально выводит следующий список
Код

<ul>
<li>Тест1
      <ul><li>Тест1</li></ul> 
</li>
<li>Тест2
      <ul><li>Тест2</li></ul>
</li>
...
<ul><li>Тест2</li></ul>
</ul>


а нужно, чтобы было так

Код

<ul>
<li>Тест1
      <ul><li>Тест1</li></ul> 
</li>
<li>Тест2
      <ul><li>Тест2</li></ul>
      <ul><li>Тест2</li></ul>
</li>
...

</ul>





--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 6.5.2014, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Вот, уже практически понятно. В коде я видел у элемента li  был атрибут id, в последнем посту в верстке его нет. Он не нужен или забыли?

Что значит "исходный массив" я не очень понял. Из него получаются массивы 1 и 2 или что? Чем массивы 1 и 2 отличаются друг от друга?
PM MAIL WWW ICQ Skype   Вверх
s1lver
Дата 6.5.2014, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Цитата(Aliance @ 6.5.2014,  12:03)
Вот, уже практически понятно. В коде я видел у элемента li  был атрибут id, в последнем посту в верстке его нет. Он не нужен или забыли?

Да, id забыл, т.к набирал в ручную код. Id содержат значения id из изходного массива(тоже успешно подставляются).

Цитата

Что значит "исходный массив" я не очень понял. Из него получаются массивы 1 и 2 или что? Чем массивы 1 и 2 отличаются друг от друга?


Исходный массив - в нем хранятся id для первого и второго уровня списка. Формируется динамически(повлиять на него нет возможности).

А массив1 и массив2 уже существуют(можно изменить как угодно), и хранят только описания для id из исходного массива.

Это сообщение отредактировал(а) s1lver - 6.5.2014, 12:15


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 6.5.2014, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Давно понятно, что исходный массив менять нет возможности, но какой он в рамках других тестовых данных - так и не понятно. Я совместил те куски кода, что были выше с конкретными значениями, получилось следующее. Если что-то не так - подправьте ПРЯМО В КОДЕ, хватит путать ;)
Код

        $elementsArray = array("501", "499", "test", "",
            "508", "506", "test", "",
            "522", "514", "test", "",
            "566", "558", "", "",
            "117", "128", "", "",
            "572", "568", "", "",
            "508", "504", "", "");
        $arr = array(
            "Тест1"=>566,
            "Тест2"=>572,
            "Тест3"=>117,
            "Тест4"=>119,
            "Тест5"=>548,
            "Тест6"=>542,
            "Тест7"=>531,
            "Тест8"=>508,
        );
        $arr_ex = array(
            "Тест1"=>560,
            "Тест2"=>554,
            "Тест3"=>562,
            "Тест4"=>564,
            "Тест5"=>558,
            "Тест6"=>556,
            "Тест7"=>552,
            "Тест8"=>550
        );
        $html = '<ul>';
        foreach(array_unique($elementsArray) as $key=>$value){
            //echo var_dump($value);
            if($key_i = array_search($value,$arr)){
                $html .= "<li id=".$value.">".$key_i;
            }
            if($key_i_ex = array_search($value,$arr_ex)){
                $html .= "<ul><li id=".$value.">".$key_i_ex."</li></ul></li>";
            }
        }
        $html .= '</ul>';
        echo $html;


Выводит
Цитата

- Тест8
- Тест1
-- Тест5
- Тест3
- Тест2


И напишите при таких данных какой output будет правильным?

Добавлено через 2 минуты и 28 секунд
Вообще код внутри цикла явно бажный. Скорее всего нужно как-то так:
Код

        $html = '<ul>';
        foreach(array_unique($elementsArray) as $key=>$value){
            //echo var_dump($value);
            if($key_i = array_search($value,$arr)){
                $html .= "<li id=".$value.">".$key_i;
                if($key_i_ex = array_search($value,$arr_ex)){
                    $html .= "<ul><li id=".$value.">".$key_i_ex."</li></ul>";
                }
                $html .= "</li>";
            }
        }
        $html .= '</ul>';
        echo $html;

PM MAIL WWW ICQ Skype   Вверх
s1lver
Дата 6.5.2014, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



Код

     $elementsArray = array("501", "499", "test", "",
            "508", "506", "test", "",
            "522", "514", "test", "",
            "566", "558", "", "",
            "117", "128", "", "",
            "572", "568", "", "",
            "508", "504", "", "");
        $arr = array(
            "Категория1"=>501,
            "Категория2"=>522,
            "Категория3"=>566,
            "Категория4"=>117,
            "Категория5"=>572,
            "Категория6"=>508
        );
        $arr_ex = array(
            "Подкатегория1"=>499,
            "Подкатегория2"=>506,
            "Подкатегория3"=>514,
            "Подкатегория4"=>558,
            "Подкатегория5"=>128,
            "Подкатегория6"=>568,
            "Подкатегория7"=>504
        );
        $html = '<ul>';
        foreach(array_unique($elementsArray) as $key=>$value){
            //echo var_dump($value);
            if($key_i = array_search($value,$arr)){
                $html .= "<li id=".$value.">".$key_i;
            }
            if($key_i_ex = array_search($value,$arr_ex)){
                $html .= "<ul><li id=".$value.">".$key_i_ex."</li></ul></li>";
            }
        }
        $html .= '</ul>';
        echo $html;

Исходный массив $elementsArray, я привел на основании вывода var_dump($elementsArray). Если заполнить его более понятными элементами, то вывод происходит такой
Категория1
Подкатегория1
Категория6
Подкатегория2
Категория2
Подкатегория3
Категория3
Подкатегория4
Категория4
Подкатегория5
Категория5
Подкатегория6
Подкатегория7
и код
Код

<ul>
<li id=501>Категория1
<ul><li id=499>Подкатегория1</li></ul></li>

<li id=508>Категория6
<ul><li id=506>Подкатегория2</li></ul></li>

<li id=522>Категория2
<ul><li id=514>Подкатегория3</li></ul></li>

<li id=566>Категория3
<ul><li id=558>Подкатегория4</li></ul></li>

<li id=117>Категория4
<ul><li id=128>Подкатегория5</li></ul></li>

<li id=572>Категория5
<ul><li id=568>Подкатегория6</li></ul></li>
<ul><li id=504>Подкатегория7</li></ul></li></ul>

Т.е в принципе, то что нужно.

Однако, этот же код, не верно работает если подставлять реальный исходный массив  smile 

Вот, так
Код

        $arr = array(
            "Категория1"=>501,
            "Категория2"=>522,
            "Категория3"=>566,
            "Категория4"=>117,
            "Категория5"=>572,
            "Категория6"=>508
        );
        $arr_ex = array(
            "Подкатегория1"=>499,
            "Подкатегория2"=>506,
            "Подкатегория3"=>514,
            "Подкатегория4"=>558,
            "Подкатегория5"=>128,
            "Подкатегория6"=>568,
            "Подкатегория7"=>504
        );
        $html = '<ul>';
        foreach(array_unique($elementsArray) as $key=>$value){
            //echo var_dump($value);
            if($key_i = array_search($value,$arr)){
                $html .= "<li id=".$value.">".$key_i;
            }
            if($key_i_ex = array_search($value,$arr_ex)){
                $html .= "<ul><li id=".$value.">".$key_i_ex."</li></ul></li>";
            }
        }
        $html .= '</ul>';
        echo $html;

уже не работает правильно.

Это сообщение отредактировал(а) s1lver - 6.5.2014, 16:29


--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
Aliance
Дата 6.5.2014, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



Аллилуйя, спустя сутки мы поняли задачу smile

Что бы я посоветовал. У вас получается исходный массив (в примере $elementsArray) состоит из блоков по 4 значения. Конечно непонятно почему его нельзя изменить, но допустим что это так, тогда мы можем воспользоваться функцией array_chunk.

Далее, я не люблю функцию array_search (O(n)), предпочитаю пользоваться функцией isset (O(1)) - соответственно предлагаю поменять ключи и значения в массивах "местами", чтобы была хеш-таблица. Если нет такой возможности, есть функция array_flip.

Еще, не до конца понял, соответствия двух массивов один-к-одному или может не быть подкатегории? В общем если второе - то нужно проверку isset, иначе просто доступ по индексу.

Получается примерно следующее:

Код

        $originalArray = array(
            "501", "499", "test", "",
            "508", "506", "test", "",
            "522", "514", "test", "",
            "566", "558", "", "",
            "117", "128", "", "",
            "572", "568", "", "",
            "508", "504", "", ""
        );
        $originalArray = array_chunk($originalArray, 4);
        $categories = array(
            "Категория1"=>501,
            "Категория2"=>522,
            "Категория3"=>566,
            "Категория4"=>117,
            "Категория5"=>572,
            "Категория6"=>508
        );
        $categories = array_flip($categories);
        $subCategories = array(
            "Подкатегория1"=>499,
            "Подкатегория2"=>506,
            "Подкатегория3"=>514,
            "Подкатегория4"=>558,
            "Подкатегория5"=>128,
            "Подкатегория6"=>568,
            "Подкатегория7"=>504
        );
        $subCategories = array_flip($subCategories);
        $html = '<ul>';
        foreach ($originalArray as $key) {
            list($categoryId, $subCategoryId) = $key;
            $html .= sprintf('<li id="category_%d">%s - %s [%d]</li>',
                $categoryId,
                $categories[$categoryId],
                $subCategories[$subCategoryId],
                $subCategoryId
            );
        }
        $html .= '</ul>';
        echo $html;

PM MAIL WWW ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0623 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.