Как получить массив определенного «ключа» в многомерный массив без зацикливания

115

Предположим, у меня есть следующий многомерный массив (полученный из MySQL или службы):

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

Можем ли мы получить массив ids за один « встроенный » вызов функции php? или одна строчка кода?
Я знаю о традиционном цикле и получении значения, но мне это не нужно:

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

Может быть, некоторые array_map()и call_user_func_array()смогут творить чудеса

ifaour
источник
«Можем ли мы получить массив идентификаторов за один вызов функции?» да, но вам придется написать функцию
:)
@ BorisGuéry, я имел в виду встроенные функции :-)
ifaour 03
2
PS: Я знаю, что могу написать foreach($users as $user) {$ids[] = $user['id'];}в одну строку! но вы понимаете, что я имею в виду / нужно :-)
ifaour
@ Евгений, очевидно, мне нужен массив для других вещей. И опять же, это только для развлечения и изучения новых сокращений в PHP.
ifaour

Ответы:

261

Начиная с php 5.5 вы можете использовать array_column:

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

Это предпочтительный вариант в любом современном проекте. Однако, если вы должны поддерживать php> 5.5, существуют следующие альтернативы:

Начиная с php 5.3, вы можете использовать array_mapанонимную функцию, например:

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

Раньше (технически php 4.0.6+) вы должны create_functionвместо этого создать анонимную функцию :

$ids = array_map(create_function('$ar', 'return $ar["id"];'), $users);
phihag
источник
Хорошо, теперь, если есть собственная функция, которая похожа на function ($ar) {return $ar['id'];}возвращаемое значение ключа, это было бы здорово! :-)
ifaour 03
1
ну, это не функция "все в одном", но Closure (анонимные функции) - очень мощная концепция, которую можно использовать для такой обработки, вам, скорее, захочется узнать, как их использовать.
Борис Гери
Что делать, если я тоже хочу получить ключ? Предположим: $ arr = ['ball' => ['basket' => 5]]; Я хочу получить: $ ball = ['ball' => 5];
Angger
2
@Angger Тогда у вас есть другой вопрос, чем этот. Не стесняйтесь спрашивать его, если вы подробно упоминаете, какое поведение вы ожидаете, например, что должно произойти, если ввод будет ['ball' => ['golf' => 7, 'basket' => 5, 'soccer' => 6], 'shuttle' => ['badminton' => 1]].
phihag
Начиная с PHP7.4 вы можете использовать array_mapфункцию стрелки:$ids = array_map(fn ($ar) => $ar['id'], $users);
user3601546
13

PHP 5.5+

Начиная с PHP5.5 +, вам доступен array_column () , что делает все перечисленное ниже устаревшим.

PHP 5.3+

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

Решение от @phihag будет безупречно работать в PHP, начиная с PHP 5.3.0, если вам потребуется поддержка до этого, вам нужно будет скопировать этот wp_list_pluck.

PHP <5.3

Wordpress 3.1+

В Wordpress есть функция wp_list_pluck. Если вы используете Wordpress, она решает вашу проблему.

PHP <5.3

Если вы не используете Wordpress , поскольку код является открытым, вы можете скопировать и вставить код в свой проект (и переименовать функцию в то, что вам больше нравится, например array_pick). Посмотреть исходный код здесь

Норрис
источник
3

Если idэто первый ключ в массиве, это сделает:

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

Однако вам не обязательно полагаться на это. :)

обмануть
источник
-1

Вы также можете использовать, array_reduce()если предпочитаете более функциональный подход

Например:

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

Или, если тебе нравится фантазия,

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

Однако этот и все вышеперечисленные методы работают за кулисами;)

Мурагури Э
источник
Ваш первый пример не вернет массив, только последнее значение, найденное для $ user ['name'] в массиве. Вам нужно нажать / добавить к $ carry и вернуть $ carry по ходу.
Progrock