Mam szereg obiektów dla kotów:
$cats = Array
(
[0] => stdClass Object
(
[id] => 15
),
[1] => stdClass Object
(
[id] => 18
),
[2] => stdClass Object
(
[id] => 23
)
)
i chcę wyodrębnić tablicę identyfikatorów kotów w 1 linii (nie jako funkcja ani pętla).
Myślałem o użyciu array_walk
z, create_function
ale nie wiem, jak to zrobić.
Dowolny pomysł?
Odpowiedzi:
Jeśli masz PHP 5.5 lub nowszy , najlepszym sposobem jest użycie wbudowanej funkcji
array_column()
:Ale syn musi być tablicą lub przekonwertowany na tablicę
źródło
array_column
nie działa ze związkiemarray
oobject
s w ogóle. Ponieważ PHP 7.0.0 jest możliwe: stackoverflow.com/a/23335938/655224Możesz użyć
array_map()
funkcji.To powinno wystarczyć:
źródło
$project_names = array_map(function($project) { return $project->name ;}, $projects );
Jednak jest to odnotowane w tym wpisie na blogu w ten sposób może być 2,5 razy wolniejsze / intensywnie wykorzystujące pamięć.create_function
pamięcią, rośnie. Jeśli napiszesz program z nieskończonymi pętlami i wywołasz w nimarray_map
withcreate_function
, zawsze pojawi sięOut of memory...
błąd. Więc nie używajcreate_function
i nie używajarray_map(function($o) { return $o->id; }, $objects);
Rozwiązanie zależy od używanej wersji PHP. Istnieją przynajmniej 2 rozwiązania:
Pierwsza (nowsze wersje PHP)
Jak powiedział wcześniej @JosepAlsina, najlepszym i zarazem najkrótszym rozwiązaniem jest użycie
array_column
:Uwaga: W celu iteracji
array
zawierającego\stdClass
es, jak użyto w pytaniu, jest to możliwe tylko w wersjach PHP>= 7.0
. Ale używającarray
zawierającegoarray
s, możesz zrobić to samo od PHP>= 5.5
.Po drugie (starsze wersje PHP)
@Greg powiedział, że w starszych wersjach PHP można wykonać następujące czynności:
Ale strzeż się: nowszych wersjach PHP
>= 5.3.0
lepiej jest używaćClosure
s, jak na przykład:Różnica
Pierwsze rozwiązanie tworzy nową funkcję i umieszcza ją w pamięci RAM. Z jakiegoś powodu moduł odśmiecania pamięci nie usuwa już utworzonej i wywołanej instancji funkcji z pamięci. I to niezależnie od tego, że utworzonej instancji funkcji nie da się już nigdy ponownie wywołać, bo nie mamy na nią wskaźnika. Następnym razem, gdy ten kod zostanie wywołany, ta sama funkcja zostanie ponownie utworzona. To zachowanie powoli wypełnia twoją pamięć ...
Oba przykłady z wyjściem pamięci, aby je porównać:
ZŁY
DOBRY
Można to również omówić tutaj
Wyciek pamięci?! Czy Garbage Collector działa dobrze, gdy używa się funkcji „create_function” w obrębie „array_map”?
źródło
array_column
w tej tablicy, zawsze zwraca to puste, podczas gdy TEN fragment działa poprawnie, oba mają chronioną właściwość, która jest dostępna w drugim fragmencie tylko. Nie mogłem znaleźć innego powodu niż przestrzeń nazw.object
w moim rozwiązanie mam na myśliobject
nie jestObject
. Mała literaobject
opisuje prosty obiekt\stdClass
. Może w tym tkwi problem. CzyObject
masztoArray
metodę? Użyj tego. Prosteobject
iarray
prawie to samo. W następstwie niezmienna musi być ważny:((object)(array)$o) === $o
. Podczas implementacji__get
metody sprawisz, że właściwości Twojej klasy będą dostępne dla każdego. Może to być oczekiwane zachowanie. Ale możesz też iterować po swoimarray<Object>
np. Zarray_map
i zadzwonićtoArray
(jeśli istnieje), a wtedy IT również działai użyj go w jednej linii :
źródło
array_walk
.KOD
WYNIK
Wiem, że używa pętli, ale to najprostszy sposób! Używając funkcji, nadal kończy się w jednej linii.
źródło
Możesz to łatwo zrobić z gadżetami ouzo
lub z Arrays (z gadżetów ouzo)
Sprawdzić: http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract
Zobacz także programowanie funkcjonalne z ouzo (nie mogę zamieścić linku).
źródło
Wbudowane pętle w PHP są szybsze niż pętle zinterpretowane, więc faktycznie ma sens, aby uczynić tę jedną linijką:
źródło
źródło
Wyjście : [1, 2]
źródło
Ta
create_function()
funkcja jest przestarzała od wersji PHP 7.2.0 . Możesz użyćarray_map()
podanego,Alternatywnie możesz użyć
array_column()
funkcji, która zwraca wartości z pojedynczej kolumny danych wejściowych, identyfikowanej przez klucz_kolumny. Opcjonalnie można podać klucz_indeksu w celu indeksowania wartości w zwracanej tablicy przez wartości z kolumny klucz_indeksu tablicy wejściowej. Możesz użyć tablicy_kolumny podanej,źródło