оператор foreach php - PullRequest
       11

оператор foreach php

1 голос
/ 08 января 2010

Мне нужно объединить два оператора foreach в один, например

foreach ($categories_stack as $category)
foreach ($page_name as $value)

Мне нужно добавить их в один оператор foreach

Возможно ли это, если да, то как?

Ответы [ 7 ]

4 голосов
/ 08 января 2010

(я не уверен, что полностью понял ваш вопрос. Я предполагаю, что вы хотите перебрать два списка параллельно)

Вы можете сделать это, используя цикл for следующим образом:

$n = min(count($category), count($value));
for($c = 0; $c < $n; $c = $c + 1){
    $categories_stack = $category[$c];
    $pagename = $value[$c];
    ...
}

Чтобы добиться того же с foreach, вам нужна функция, аналогичная zip() функции Python.

В Python это будет:

for categories_stack, pagename in zip(categories, values):
     print categories_stack, pagename

Поскольку в PHP нет стандартной функции zip(), вам придется написать такую ​​функцию самостоятельно или воспользоваться циклическим решением for.

3 голосов
/ 08 января 2010

Вы можете делать вложенные foreach, если это то, что вы хотите. Но, не зная больше ваших данных, невозможно сказать, поможет ли это:

foreach ($categories_stack as $category) {
    foreach ($page_name as $value) {
    }
}

Возможно, вы хотите распечатать все страницы в категории? Это, вероятно, не сработает, поэтому вы можете дать немного больше информации о том, как массивы выглядят и связаны друг с другом?

2 голосов
/ 08 января 2010

Этот цикл будет продолжаться до длины самого длинного массива и будет возвращать ноль, если в одном из массивов нет соответствующих элементов. Попробуйте!

$a = array(1 => "a",25 => "b", 10 => "c",99=>"d");
$b = array(15=>1,5=>2,6=>3);

$ao = new ArrayObject($a);
$bo = new ArrayObject($b);
$ai = $ao->getIterator();
$bi = $bo->getIterator();
for (
    $ai->rewind(),$bi->rewind(),$av = $ai->current(),$bv = $bi->current();
    list($av,$bv) =
        array(
            ($ai->valid() ? $ai->current() : null),
            ($bi->valid() ? $bi->current() : null)
        ), 
    ($ai->valid() || $bi->valid());
    ($ai->valid() ? $ai->next() : null),($bi->valid() ? $bi->next() : null))
{
    echo "\$av = $av\n";
    echo "\$bv = $bv\n";
}

Я не могу точно сказать из вопроса, как именно вы хотите пересечь два массива. Для вложенного foreach вы просто пишете

foreach ($myArray as $k => $v) {
    foreach ($mySecondArray as $kb => $vb {
    }
}

Однако вы можете делать все что угодно с некоторым творческим использованием функций обратного вызова. В этом случае анонимная функция возвращает два элемента из каждого массива на каждой итерации. Затем легко использовать значение итерации в виде массива или разбить его на переменные, используя list(), как показано ниже.

Это также дает дополнительное преимущество работы независимо от структуры ключа. Я чисто основан на упорядочении элементов массива. Просто используйте соответствующую функцию сортировки, если элементы не в порядке.

Он не беспокоится о длине массивов, так как об ошибках не сообщается, поэтому следите за пустыми значениями.

$a = array("a","b","c");
$b = array(1,2,3);
foreach (
        array_map(
            create_function(
                '$a,$b', 'return array($a,$b);'
            )
            ,$a,$b
        )
        as $value
    ) 
{
    list($a,$b) = $value;
    echo "\$a = $a\n";
    echo "\$b = $b\n";
}

выход

$a = a
$b = 1
$a = b
$b = 2
$a = c
$b = 3

Вот еще один вариант для вас, который останавливается на окончании любого из списков. То же, что и использование min(count(a),count(b). Полезно, если у вас есть массивы одинаковой длины. Если кто-то может сделать это, продолжайте к max(count(a),count(b)), дайте мне знать.

$ao = new ArrayObject($a);
$bo = new ArrayObject($b);
$ai = $ao->getIterator();
$bi = $bo->getIterator();
for (
    $ai->rewind(),$bi->rewind();
    $av = $ai->current(),$bv=$bi->current();
    $ai->next(),$bi->next())
{
    echo "\$av = $av\n";
    echo "\$bv = $bv\n";
}
1 голос
/ 08 января 2010

Конечно, вы можете просто объединить массивы перед циклом?

$data = array_merge($categories_stack, $page_name);

foreach($data AS $item){
...
}
1 голос
/ 08 января 2010

Здесь пригодится почтенный цикл:

for(
    $i = 0,
    $n = sizeof($categories_stack),
    $m = sizeof($page_name);

    $i < $n && $i < $m;

    $i++
) {
    $category = $categories_stack[$i];
    $value = $page_name[$i];

    // do stuff here ....
}
0 голосов
/ 08 января 2010

Имеют ли элементы массива прямое соответствие друг другу, то есть есть ли элемент в $page_name для каждого элемента в $categories_stack? Если это так, просто переберите значения ключей и (при условии, что они имеют одинаковые ключи):

foreach ($categories_stack as $key => $value)
{
    $category = $value;
    $page = $page_name[$key];

    // ...
}
0 голосов
/ 08 января 2010

Не могли бы вы просто вложить их с переменными, выходящими за рамки foreach, или предварительно сохранить содержимое в виде массива, подобного настройке KVP? Мой ответ неопределенный, но я не совсем уверен, почему вы пытаетесь это сделать.

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