Czy w PHP można spłaszczyć tablicę wymiarową (bi / multi) bez użycia rekurencji lub referencji?
Interesują mnie tylko wartości, więc klucze można zignorować, myślę w wierszach array_map()
i array_values()
.
php
arrays
multidimensional-array
flatten
Alix Axel
źródło
źródło
Odpowiedzi:
Możesz użyć Standardowej Biblioteki PHP (SPL), aby „ukryć” rekursję.
odciski
źródło
iterator_to_array($it, false)
unika potrzeby foreach.function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }
Mam nadzieję, że to pomaga innym.W PHP 5.3 najkrótszym rozwiązaniem wydaje się być
array_walk_recursive()
nowa składnia zamknięć:źródło
use
składni, aby działała,array_walk_recursive
ponieważ nie akceptuje$userdata
parametru opcjonalnego przez odniesienieRozwiązanie dla 2-wymiarowej tablicy
Spróbuj tego:
EDYCJA: 21 sierpnia-13
Oto rozwiązanie, które działa dla macierzy wielowymiarowej:
Patrz: http://php.net/manual/en/function.call-user-func-array.php
źródło
call_user_func_array('array_merge', [])
(zwróć uwagę na pustą tablicę) zwraca null i wyzwala błąd ostrzegawczy php. Jest to łatwe rozwiązanie, jeśli wiesz na pewno, że tablica nie będzie pusta, ale nie jest to częste założenie, które wielu może poczynić.$result = $array ?call_user_func_array('array_merge', $array) : [];
W PHP 5.6 i nowszych możesz spłaszczyć tablice dwuwymiarowe
array_merge
po rozpakowaniu tablicy zewnętrznej za pomocą...
operatora. Kod jest prosty i przejrzysty.Działa to również z kolekcją tablic asocjacyjnych.
Ale to nie działa, gdy zewnętrzna tablica ma klucze nienumeryczne. W takim przypadku najpierw musisz zadzwonić
array_values
.Aktualizacja: Na podstawie komentarza @MohamedGharib
To wyrzuci błąd, jeśli tablica zewnętrzna jest pusta, ponieważ
array_merge
zostałaby wywołana z zerowymi argumentami. Można tego uniknąć, dodając pustą tablicę jako pierwszy argument.źródło
array_merge([], ...$a);
Aby spłaszczyć bez rekurencji (tak jak prosiłeś), możesz użyć stosu . Oczywiście możesz wprowadzić tę funkcję jako własną
array_flatten
. Oto wersja, która działa bez kluczy :.Elementy przetwarzane są w kolejności. Ponieważ podelementy zostaną przeniesione na stos, zostaną one przetworzone w następnej kolejności.
Możliwe jest również uwzględnienie kluczy, jednak do obsługi stosu potrzebna będzie inna strategia. Jest to konieczne, ponieważ musisz poradzić sobie z możliwymi duplikatami kluczy w pod-tablicach. Podobna odpowiedź w pokrewnym pytaniu: PHP Przejdź przez wielowymiarową tablicę zachowując klucze
Nie jestem do końca pewien, ale II przetestowałem to w przeszłości:
RecurisiveIterator
używa rekurencji, więc zależy to od tego, czego naprawdę potrzebujesz. Powinno być również możliwe utworzenie iteratora rekurencyjnego na podstawie stosów:Próbny
Do tej pory nie udało mi się wdrożyć stosu, na podstawie
RecursiveIterator
którego moim zdaniem jest to dobry pomysł.źródło
if(!empty($value)){$flat[] = $value}
wewnątrz instrukcji else, aby zapobiec dodaniu pustego do tablicy wyników. Niesamowita funkcja!Prosta i jednokierunkowa odpowiedź.
Stosowanie:
Wyjście (w PsySH):
Teraz zależy od ciebie, jak poradzisz sobie z kluczami. Twoje zdrowie
EDYCJA (2017-03-01)
Cytując problem / problem Nigela Aldertona :
Cytując odpowiedź Svisha :
źródło
$array = ['a',['b','c']]
staje sięArray ([0] => b, [1] => c )
.'a'
Jest stracone, ponieważ'b'
ma również klucz0
.false
jako drugi parametr ($use_keys
) doiterator_to_array
wywołania.Wykorzystuje rekurencję. Mam nadzieję, że po zobaczeniu, jak to nie jest skomplikowane, twój strach przed rekurencją rozproszy się, gdy zobaczysz, jak to nie jest skomplikowane.
Wynik:
źródło
Pomyślałem, że zwrócę uwagę na to, że jest to fold, więc można użyć array_reduce:
EDYCJA: Zauważ, że można to skomponować w celu spłaszczenia dowolnej liczby poziomów. Możemy to zrobić na kilka sposobów:
Oczywiście, moglibyśmy również użyć pętli, ale pytanie wymaga funkcji kombinatorycznej wzdłuż linii array_map lub array_values.
źródło
fold
ją ustawić na 4 poziomy, albofold . fold
uzyskać 3 poziomy, albofold . fold . fold
uzyskać 2 poziomy itp. Zapobiega to również ukrywaniu się błędów; na przykład. jeśli chcę spłaszczyć tablicę 5D, ale dostaję tablicę 4D, błąd zostanie natychmiast wyzwolony.$concat
, myślę, że powinieneś to po prostu nazwać$flatten
.array_merge
jest php odpowiednikiem concat. Próbowałem zostaćarray_concat
dodany jako alias dlaarray_merge
.Spłaszcza tylko tablice dwuwymiarowe:
źródło
To rozwiązanie nie jest rekurencyjne. Zauważ, że kolejność elementów będzie nieco mieszana.
źródło
shifting
wartość poza tablicą i ponowne dołączenie jej na końcu nie ma większego sensu. Chybaarray_merge()
zamiast tego chciałeś ?Uważam, że jest to najczystsze rozwiązanie bez użycia mutacji ani nieznanych klas.
źródło
Wypróbuj następującą prostą funkcję:
Więc z tego:
dostajesz:
źródło
Sztuczka polega na przekazywaniu tablic źródłowej i docelowej przez odniesienie.
źródło
Fragment kodu
źródło
Możesz to zrobić za pomocą gadżetów ouzo :
Zobacz: tutaj
źródło
Jeśli naprawdę nie lubisz rekurencji ... spróbuj zamiast tego zmienić :)
Uwaga: W tej prostej wersji nie obsługuje kluczy tablicy.
źródło
continue
, będzie nieco szybszy.Co powiesz na użycie generatora rekurencyjnego? https://ideone.com/d0TXCg
źródło
Dla php 5.2
źródło
Ta wersja może wykonywać głębokie, płytkie lub określoną liczbę poziomów:
źródło
Ponieważ kod tutaj wygląda przerażająco. Oto funkcja, która przekształci również tablicę wielowymiarową w składnię zgodną z formą HTML, ale jest łatwiejsza do odczytania.
źródło
Można to osiągnąć za pomocą
array_walk_recursive
Przykład roboczy: - https://3v4l.org/FpIrG
źródło
Oto moje rozwiązanie, korzystając z referencji:
źródło
źródło
Oto uproszczone podejście:
źródło
Każdy, kto szuka naprawdę czystego rozwiązania tego problemu; oto opcja:
Wydruki
źródło
Wystarczy opublikować jakieś inne rozwiązanie)
źródło
Jeśli chcesz zachować swoje klucze, to jest rozwiązanie.
Niestety generuje tylko końcowe zagnieżdżone tablice, bez środkowych klawiszy. W poniższym przykładzie:
Dane wyjściowe to:
źródło
Musiałem reprezentować wielowymiarową tablicę PHP w formacie wejściowym HTML.
źródło
$var['a']['b']['c'][0] = 'a'; ...
.Jeśli masz tablicę obiektów i chcesz spłaszczyć ją za pomocą węzła, po prostu użyj tej funkcji:
źródło