PDA

Просмотр полной версии : есть ли способ управлять foreach?


Дикс
01.03.2010, 13:58
думал спросить в теме для новичков, но потом решил что этот вопрос не относится к основам и может быть интересен не только мне.

интересно, есть ли способ управлять foreach?
в частности - при определенном условии вернуть его на предыдущую позицию

т.е. к примеру

foreach($keys as $key)
{

echo $key;
if($key == ...)
prev($key); // не работает
}

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


PS я знаю про for(), хочется обойтись без него

Kaimi
01.03.2010, 14:09
PS я знаю про for(), хочется обойтись без него

Почему?
Воспользуйся while тогда)

oRb
01.03.2010, 14:11
http://ru2.php.net/manual/en/control-structures.foreach.php
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself
Поэтому:
$keys = range(1, 5);
while(list($value, $key) = each($keys)) {
if($key == 3)
next($keys);

echo $key . "\n";
}

Результат:

1
2
3
5

Pashkela
01.03.2010, 14:22
если я правильно понял ТС:


<?php
$array = range(1,5);
$flag = true;
while($current = current($array)) {
echo $current . "<br>";
next($array);
if ($current == 2 && $flag) {
prev($array);
$flag = false;
}
}
?>


Результат:

1
2
2
3
4
5

Дикс
01.03.2010, 15:12
ну да, в целом реализация позволяет добиться того что нужно

но тут надо сказать, почему я не хочу использовать for, в котором достаточно написать $i--


$keys = ...
$size = sizeof($keys);
for($i = 0; $i < $size; $i++)
{

$key = $keys[$i];
echo $key;

}


а в случае с foreach()


$keys = ...
foreach($keys as $key)
{

echo $key;

}


не хватает лишь возможности открутить его обратно при условии

я знаю что фореач это копия, узрел как-то в учебнике по плюсам
но это нисколько не оправдывает отсутствие такой возможности

ну и вариант с each() ещё более ужасен в плане красоты кода


судя по всему простого решения нет, поэтому всем спасибо, не заморачивайтесь над этим. просто у меня такие вот нездоровые стремления :)

dr.Web
02.03.2010, 23:31
next() prev() current()

criptic
02.03.2010, 23:39
оператор foreaM ты гарантированно получишь каждый элемент, поскольку не потребуется вручную устанавливать цикл и запрашивать счетчик, а оператор, содержащийся в цикле, автоматически поместит элемент в указанную тобой переменную — достаточно лишь сослаться на нее в этом операторе.

Pashkela
03.03.2010, 00:05
какие мы умные, а теперь прочитайте первый пост темы

criptic
03.03.2010, 00:06
Оу, сори

dr.Web
03.03.2010, 00:08
foreach($keys as $i=>$key)
{

echo $key;
if($key == ...)
$keys[$i-1];
}

Pashkela
03.03.2010, 00:09
foreach($keys as $i=>$key)
{

echo $key;
if($key == ...)
$keys[$i-1];
}



а теперь запусти свой скрипт и перечитай первый пост снова

shellz[21h]
03.03.2010, 00:10
не хватает лишь возможности открутить его обратно при условии
Используй do {....} while(....);
ну и вариант с each() ещё более ужасен в плане красоты кода
типа гламурный кодер))

dr.Web
03.03.2010, 01:42
а теперь запусти свой скрипт и перечитай первый пост снова


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

что не так?




foreach($keys as $i=>$key)
{

echo $key; //показыввает текущий элемент
if($key == ...) //если $key == ... то
$keys[$i-1]; //показывает предыдущий элемент
}

Pashkela
03.03.2010, 01:46
уже писал - запусти скрипт, проверь, предварительно прочитай первый пост, не выставляй себя идиотом

dr.Web
03.03.2010, 01:50
уже писал - запусти скрипт, проверь, предварительно прочитай первый пост, не выставляй себя идиотом
идиотом себя выставляешь ты я и без запуска знаю что получиться.

//непонял наверное первый пост...

Pashkela
03.03.2010, 01:57
идиотом себя выставляешь ты я и без запуска знаю что получиться.

//непонял наверное первый пост...

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

m0Hze
03.03.2010, 02:00
идиотом себя выставляешь ты я и без запуска знаю что получиться.

//непонял наверное первый пост...Омг

dr.Web
03.03.2010, 02:01
Ок, покажи пример скрипта на основании своего алгоритма, отвечающего условиям, озвученным в первом посте, чтобы смыть с себя все то заслуженное говно, которым я тебя заслуженно облил.

на



$keys=range(1,100);


foreach($keys as $i=>$key)
{

echo $key."<br>";
if($key == 20){echo $keys[$i]."<br>";}
}


exit;




обливатель. ;)





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

dr.Web
03.03.2010, 02:06
можно ввести ещё одну переменную в которой будет храниться нужный индекс массива.

Pashkela
03.03.2010, 02:13
молодец, а говорил не знаешь

в частности - при определенном условии вернуть его на предыдущую позицию

а теперь представь, что не на предыдущую, а на две-двадцать назад, и ключи у массива не идут так - 1,2,3,4,5,6, а, например, так - 1,11,34,45,67,89,90

PS: И потом ты не вернул на предыдущую позицию, а просто повторил два раза текущую, разницу чуствуешь?

dr.Web
03.03.2010, 02:18
молодец, а говорил не знаешь



а теперь представь, что не на предыдущую, а на две-двадцать назад, и ключи у массива не идут так - 1,2,3,4,5,6, а, например, так - 1,11,34,45,67,89,90

тогда while :p

Pashkela
03.03.2010, 02:19
а вот и нет, вопрос был про foreach )) Ну просто представь себе, нет while

dr.Web
03.03.2010, 02:28
вот смотри его код

foreach($keys as $key)
{

echo $key;
if($key == ...)
prev($key); // не работает
}


ясен хрен не будет работать prev()
$key этож не массив


а если попробовать так(просто поправка скрипта ТСа :) )

$keys=range(1,100);


foreach($keys as $i=>$key)
{
echo $key."<br>";
if($key == 20){echo prev($keys)."<br>";}
}

Pashkela
03.03.2010, 02:31
вот теперь да)

dr.Web
03.03.2010, 02:34
тс пропал наверно уже неактуал тема ))

SQLHACK
04.03.2010, 01:08
Поставим жирную точку!

Foreach не умеет возможности управлением индексом, он всегда идет от первого к последнему элементу.

Но если вам все таки требуется такая возможность, то решается она с помощью цикла While

Далее код демонстрирующий как это делается:
<?php
$array = array ( 'a', 'b', 'c', 'd', 'e', 'f') ;

//Флаг направления, закоментируй одну из двух
$flag = 0;reset($array); //вперед
//$flag = 1;end ($array); //назад


while($value = current($array)){
echo $value."\r\n<br>";
if($flag == 0){ //Следующий элемент
next($array);
}elseif($flag == 1){ //Предыдущий элемент
prev($array);
}
}

?>

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