Jak uzyskać tablicę określonego „klucza” w wielowymiarowej tablicy bez zapętlania

115

Załóżmy, że mam następującą tablicę wielowymiarową (pobraną z MySQL lub usługi):

array(
    array(
        [id] => xxx,
        [name] => blah
    ),
    array(
        [id] => yyy,
        [name] => blahblah
    ),
    array(
        [id] => zzz,
        [name] => blahblahblah
    ),
)

Czy możemy uzyskać tablicę ids w jednym „ wbudowanym ” wywołaniu funkcji php? czy jedna linia kodu?
Zdaję sobie sprawę z tradycyjnego zapętlania i uzyskiwania wartości, ale nie potrzebuję tego:

foreach($users as $user) {
    $ids[] = $user['id'];
}
print_r($ids);

Może trochę array_map()i call_user_func_array()potrafią zrobić magię.

ifaour
źródło
„Czy możemy uzyskać tablicę identyfikatorów w jednym wywołaniu funkcji?” tak, ale będziesz musiał wpisać funkcję
:)
@ BorisGuéry, miałem na myśli funkcje wbudowane :-)
ifaour
2
PS: Wiem, że mogę pisać foreach($users as $user) {$ids[] = $user['id'];}w jednej linii! ale wiesz, co mam na myśli / potrzebuję :-)
ifaour
@Eugene, oczywiście potrzebuję tablicy do innych celów. I znowu, to jest tylko dla zabawy i nauki nowych skrótów w PHP.
ifaour

Odpowiedzi:

261

Od php 5.5 możesz używać array_column:

$ids = array_column($users, 'id');

Jest to preferowana opcja w każdym nowoczesnym projekcie. Jeśli jednak musisz obsługiwać php> 5.5, istnieją następujące alternatywy:

Od php 5.3 możesz używać array_mapz anonimową funkcją, taką jak ta:

$ids = array_map(function ($ar) {return $ar['id'];}, $users);

Przed (technicznie php 4.0.6+) musisz utworzyć anonimową funkcję z create_function:

$ids = array_map(create_function('$ar', 'return $ar["id"];'), $users);
phihag
źródło
fajnie, teraz, jeśli istnieje natywna funkcja, która jest podobna do function ($ar) {return $ar['id'];}zwracanej wartości klucza, byłaby niesamowita! :-)
ifaour
1
cóż, to nie jest funkcja „wszystko w jednym”, ale Closure (funkcje anonimowe) to bardzo potężna koncepcja, której można użyć do takiego przetwarzania, wolisz wiedzieć, jak ich używać.
Boris Guéry
A jeśli ja też chcę dostać klucz? Załóżmy: $ arr = ['ball' => ['basket' => 5]]; Chcę dostać: $ ball = ['ball' => 5];
Angger
2
@Angger W takim razie masz inne pytanie niż to. Możesz o to zapytać, o ile szczegółowo określisz, jakiego zachowania się spodziewasz, na przykład co powinno wyniknąć, jeśli dane wejściowe są ['ball' => ['golf' => 7, 'basket' => 5, 'soccer' => 6], 'shuttle' => ['badminton' => 1]].
phihag
Od PHP7.4 możesz używać array_mapz funkcją strzałki:$ids = array_map(fn ($ar) => $ar['id'], $users);
user3601546
13

PHP 5.5+

Rozpoczynając PHP5.5 + masz dostępną tablicę_kolumny () , co sprawia, że ​​wszystkie poniższe elementy są nieaktualne.

PHP 5.3+

$ids = array_map(function ($ar) {return $ar['id'];}, $users);

Rozwiązanie autorstwa @phihag będzie działało bezbłędnie w PHP począwszy od PHP 5.3.0, jeśli wcześniej potrzebujesz wsparcia, będziesz musiał skopiować to wp_list_pluck.

PHP <5.3.0

Wordpress 3.1+

W Wordpress jest funkcja o nazwie wp_list_pluck Jeśli używasz Wordpressa, która rozwiązuje Twój problem.

PHP <5.3.0

Jeśli nie używasz Wordpress , ponieważ kod jest open source, możesz skopiować, wkleić kod do swojego projektu (i zmienić nazwę funkcji na preferowaną, np. Array_pick). Zobacz źródło tutaj

Norris
źródło
3

Jeśli idjest to pierwszy klucz w tablicy, to wystarczy:

$ids = array_map('current', $users);

Jednak niekoniecznie powinieneś na tym polegać. :)

zamrozić
źródło
-1

Możesz również użyć, array_reduce()jeśli wolisz bardziej funkcjonalne podejście

Na przykład:

$userNames = array_reduce($users, function ($carry, $user) {
    array_push($carry, $user['name']);
    return $carry;
}, []);

Lub jeśli lubisz być fantazyjny,

$userNames = [];
array_map(function ($user) use (&$userNames){
    $userNames[]=$user['name'];
}, $users);

Ta i wszystkie powyższe metody działają jednak w pętli za kulisami;)

Muraguri E.
źródło
Twój pierwszy przykład nie zwróci tablicy, tylko ostatnią wartość znalezioną dla $ user ['name'] w tablicy. Musisz wcisnąć / dołączyć do $ carry i zwracać $ carry na bieżąco.
Progrock