Глядя вперед или назад в цикле foreach - PullRequest
0 голосов
/ 18 января 2011

Я отображаю навигацию из двумерного массива, используя списки, как показано:

<ul> <li>parent 
<ul> <li>level 1</li> <li>level 1

<ul> <li>level 3</li> </ul>

</li> </ul>

<li> </ul>

</li> </ul>

В любом случае, чтобы правильно закрыть <li> и </ul>, я нахожу, что мне нужны данные из следующего массивав последовательности foreach.Как я могу получить это?

Ответы [ 6 ]

4 голосов
/ 18 января 2011

Хотя в прошлом у меня были нестабильные результаты, вы можете использовать следующие функции для перемещения текущего указателя массива.

Надеюсь, это поможет.

1 голос
/ 18 января 2011

Вот решение:

$arr = array(1,2,3,4,5);

foreach ($arr as $foo) {
    if (empty($isrewind)) {
       reset($arr);
       $isrewind = true;
    }

    echo "node: $foo\n";

    $copy = $arr;   // make a copy of the array
    $next = next($copy);
    echo "next: $next\n";

    $copy = $arr;   // make a copy of the array
    $prev = prev($copy);
    echo "prev: $prev\n";

    next($arr);     // don't forget to advance the pointer on the original array
}

Я продемонстрировал бит prev только для примера.Вы можете легко сделать это без prev(), сохранив элемент в конце каждой итерации.

Бит if empty сбрасывает указатель массива в начало, потому что foreach передвигает указатель один раз, когдаделает копию массива.

Приведенный выше пример дает:

node: 1
next: 2
prev: 

node: 2
next: 3
prev: 1

node: 3
next: 4
prev: 2

node: 4
next: 5
prev: 3

node: 5
next: 
prev: 4

Если вам нужно сделать что-то подобное, то может быть лучшим способом, простоизменив структуру данных (трудно сказать без кода).

0 голосов
/ 18 января 2011

Нашел ответ, уставившись мне в лицо.Получил нужные мне массивы так:

foreach ($ tree as $ key => $ link) {

$ level = $ link ['level'];

$ next_key = $ key + 1;

$ prev_key = $ key-1;

$ next_array = $ tree [$ next_key];

$ prev_array = $ tree [$ prev_key];

И тогда я мог бы протестировать свойство уровня (указывающее на deph внутри дерева навигации) с помощью набора операторов if для правильной вставки закрывающей разметки.

Грязный код, и я не горжусь им, но он работает!

Довольно рассержен на себя за то, что не видел его раньше.

0 голосов
/ 18 января 2011

Не уверен, просит ли он об этом, но вот мой выстрел

$list = array (
    'Home page' => null,
    'Articles'  => array (
        'Diving'    => null,
        'Skydiving' => null,
        'Stackoverflowing'  => null,
    ),
    'Nobody cares'  => array (
        'Hey'   => null,
        'It is just a test' => null,
    ),
);

function render_menu ($list)
{
    echo "<ul>\n";
    foreach ($y = new RecursiveArrayIterator ($list, RecursiveIteratorIterator::SELF_FIRST) as $key => $item)
    {
        if ($y->hasChildren ())
        {
            echo "<li>$key\n";
            render_menu ($item);
            echo "</li>\n";
        }
        else
        {
            echo "<li>$key</li>\n";
        }
    }
    echo "</ul>\n";
}

render_menu ($list);
0 голосов
/ 18 января 2011

IHMO невозможно с простым циклом foreach для массива с нечисловыми индексами.Но вы можете расширить класс SPL CachingIterator , чтобы обернуть ваш массив в это.В вашем расширенном классе вы можете реализовать методы для возврата предыдущего и следующего индекса / значения без продвижения внутреннего указателя элемента.

Если у вас есть массив с числовыми индексами, используйте цикл for вместо foreach.Затем вы можете использовать $i+1 и $i-1 для просмотра индексов массива, отличных от текущего индекса.

0 голосов
/ 18 января 2011

Я полагаю, вы используете php. Я не думаю, что это возможно, вы должны знать индекс элемента и индексировать массив. Sth, как это:

$i=0;
foreach ($array as $element){
    echo $element;
    //do sth with $array[$i+1];
    //do sth with $array[$i-1];
    $i++;
}

Не имею никакой другой подсказки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...