Pytanie jest proste. Mam foreach
pętlę w kodzie:
foreach($array as $element) {
//code
}
W tej pętli chcę inaczej reagować, gdy jesteśmy w pierwszej lub ostatniej iteracji.
Jak to zrobić?
Możesz użyć licznika:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
array_shift
iarray_pop
. Chociaż to jest rozwiązanie, które wymyśliłem, gdybym musiał wdrożyć coś takiego, trzymałbym się teraz odpowiedzi Rok Kralja .$i = 1
, nie musisz się martwić$len - 1
, po prostu użyj$len
.Jeśli wolisz rozwiązanie, które nie wymaga inicjalizacji licznika poza pętlą, proponuję porównanie bieżącego klucza iteracji z funkcją, która mówi ci ostatni / pierwszy klucz tablicy.
Staje się to nieco bardziej wydajne (i bardziej czytelne) w nadchodzącym PHP 7.3.
Rozwiązanie dla PHP 7.3 i nowszych:
Rozwiązanie dla wszystkich wersji PHP:
źródło
end()
+key()
na każdej iteracji pętli - jeśli to obie, to za każdym razem wywoływane są 4 metody. To prawda, że byłyby to bardzo lekkie operacje i prawdopodobnie są to po prostu wyszukiwanie wskaźników, ale potem dokumenty określają toreset()
iend()
modyfikują wewnętrzny wskaźnik tablicy - więc czy jest szybszy niż licznik? być może nie.reset()
rozmowę przed foreach i zapisać wynik w pamięci podręcznej$first
.Aby znaleźć ostatni element, uważam, że ten fragment kodu działa za każdym razem:
źródło
next
: Ostrzeżenie Ta funkcja może zwracać wartość logicznąFALSE
, ale może również zwracać wartość inną niż logiczna, której wynikiem jest wartośćFALSE
. Aby uzyskać więcej informacji, przeczytaj sekcję dotyczącą wartości logicznych. Użyj===
operatora do przetestowania wartości zwracanej przez tę funkcję.[true,true,false,true]
. Ale osobiście będę tego używał za każdym razem, gdy mam do czynienia z tablicą, która nie zawiera wartości logicznejfalse
.next()
NIGDY nie powinien być używany wewnątrz pętli foreach. Zmiesza wskaźnik wewnętrzny tablicy. Sprawdź dokumentację, aby uzyskać więcej informacji.Bardziej uproszczona wersja powyższego i zakładając, że nie używasz niestandardowych indeksów ...
Wersja 2 - Ponieważ nienawidzę używać innych, chyba że jest to konieczne.
źródło
if ($index == count($array) - 1)
. Zobacz tutaj .Możesz usunąć pierwszy i ostatni element z tablicy i przetwarzać je osobno.
Lubię to:
Usunięcie całego formatowania do CSS zamiast tagów wbudowanych poprawiłoby kod i przyspieszyło ładowanie.
W miarę możliwości można także unikać mieszania HTML z logiką php.
Twoja strona może stać się o wiele bardziej czytelna i łatwa w utrzymaniu, dzieląc takie rzeczy:
źródło
Próbą znalezienia pierwszego byłoby:
źródło
Po prostu to działa!
Dziękuję @billynoah za rozwiązanie problemu końcowego .
źródło
if ($key === $lastkey)
.if ($lastkey === $key)
?PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
otrzymuje liczbę całkowitą, nieend()
.end()
„ zwraca wartość ostatniego elementu ” ikey()
oczekuje tablicy jako danych wejściowych.1: Dlaczego nie użyć prostego
for
stwierdzenia? Zakładając, że używasz prawdziwej tablicy, a nie an,Iterator
możesz łatwo sprawdzić, czy zmienna licznika jest równa 0, czy jeden mniejsza niż cała liczba elementów. Moim zdaniem jest to najbardziej czyste i zrozumiałe rozwiązanie ...2: Należy rozważyć użycie zestawów zagnieżdżonych do przechowywania struktury drzewa. Dodatkowo możesz ulepszyć całość, korzystając z funkcji rekurencyjnych.
źródło
for
można od pętli1
don-1
i wziąćif
s poza ciałem. Nie ma sensu sprawdzać ich wielokrotnie.Najlepsza odpowiedź:
źródło
Najbardziej wydajna odpowiedź z @morg, w przeciwieństwie do
foreach
, działa tylko dla odpowiednich tablic, a nie dla obiektów mapy mieszania. Ta odpowiedź pozwala uniknąć narzutu instrukcji warunkowej dla każdej iteracji pętli, tak jak w większości tych odpowiedzi (w tym odpowiedzi zaakceptowanej) poprzez specyficzną obsługę pierwszego i ostatniego elementu oraz zapętlanie elementów środkowych.array_keys
Funkcja może być użyta do dokonania efektywnej pracy odpowiedzi jakforeach
:Nie przeprowadziłem testów porównawczych w tym zakresie, ale do pętli nie dodano żadnej logiki, która jest największym hitem wydajności, więc podejrzewam, że testy porównawcze z wydajną odpowiedzią są dość zbliżone.
Jeśli chcesz funkcjonalizować tego rodzaju rzeczy, podważyłem tutaj funkcję iterateList . Możesz jednak chcieć przetestować kod GIST, jeśli bardzo martwisz się wydajnością. Nie jestem pewien, ile narzucają wszystkie wywołania funkcji.
źródło
W przypadku skryptów generujących zapytania SQL lub czegokolwiek, co wykonuje inną akcję dla pierwszego lub ostatniego elementu, jest to znacznie szybsze (prawie dwa razy szybsze), aby uniknąć niepotrzebnego sprawdzania zmiennych.
Obecnie akceptowane rozwiązanie wykorzystuje pętlę i sprawdzanie w pętli, które będzie wykonywane co każde pojedyncze sformułowanie, poprawny (szybki) sposób to zrobić:
Mały domowy test porównawczy pokazał, co następuje:
test1: 100000 serii modelu Morg
czas: 1869.3430423737 milisekund
test2: 100000 serii modelu, jeśli ostatnia
czas: 3235.6359958649 milisekund
I dlatego jest całkiem jasne, że czek kosztuje dużo i oczywiście staje się jeszcze gorzej, gdy dodajesz więcej zmiennych czeków;)
źródło
$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;
wyświetli:0: , 1: One, 2: ,
array()
jest,{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
ale puste elementy są ignorowane przy pomocy count, liczy się liczba zdefiniowanych „rzeczy” !! BOUNTY OFIARY POCHODZĄCE! Ta odpowiedź zasługuje na nagrodę, ale jeśli @Morg. odszedł, to nie ma sensu. Dałbym nagrodę osobie, która prawdopodobnie nie użyje SO ponownie! Jeśli wróci i poprawi odpowiedź, zasługuje na nagrodę!array_keys
funkcji, którą można traktować jak tablicę. Zobacz moją „ulepszoną” odpowiedź .$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
W przypadku kluczy i wartości działa to również:
źródło
Korzystanie ze zmiennej boolowskiej jest nadal najbardziej niezawodne, nawet jeśli chcesz sprawdzić pierwsze pojawienie się zmiennej
$value
(uznałem ją za bardziej przydatną w mojej sytuacji i w wielu sytuacjach) , na przykład:Więc jak
!next( $array )
znaleźć ostatni,$value
który zwróci,true
jeśli nie manext()
wartości do iteracji.I wolę użyć
for
pętli, niżforeach
gdybym miał użyć licznika, takiego jak to:źródło
Natknąłem się na ten wątek, gdy mam ten sam problem. Muszę tylko zdobyć pierwszy element, a następnie ponownie przeanalizować kod, dopóki nie przyszło mi to do głowy.
Powyższe kody są świetne i kompletne, ale jeśli potrzebujesz tylko pierwszego elementu, możesz wypróbować ten kod.
źródło
Nie jestem pewien, czy nadal jest to konieczne. Ale poniższe rozwiązanie powinno współpracować z iteratorami i nie wymaga
count
.źródło
Możesz także użyć funkcji anonimowej:
Należy wymienić jeszcze trzy rzeczy:
array_values
.$element
, musisz przekazać go przez referencję (&$element
).$indexOfLastElement
wewnątrzuse
konstrukcji, przez odniesienie ponownie w razie potrzeby.źródło
Możesz użyć licznika i długości tablicy.
źródło
źródło
Korzystanie z resetowania ($ array) i end ($ array)
Demo repl.it
źródło
Spróbuj tego:
źródło