PHP – Извлечение свойства из массива объектов

У меня есть массив объектов кошек:

$cats = Array ( [0] => stdClass Object ( [id] => 15 ), [1] => stdClass Object ( [id] => 18 ), [2] => stdClass Object ( [id] => 23 ) ) 

и я хочу извлечь массив идентификаторов кошек в 1 строку (а не функцию или цикл).

Я думал об использовании array_walk с create_function но я не знаю, как это сделать.

Есть идеи?

Solutions Collecting From Web of "PHP – Извлечение свойства из массива объектов"

Вы можете использовать array_map() .
Это должно сделать это:

 $catIds = array_map(create_function('$o', 'return $o->id;'), $objects); 

Если у вас есть PHP 5.5 или новее , лучший способ – использовать встроенную функцию array_column() :

 $idCats = array_column($cats, 'id'); 

Но сын должен быть массивом или преобразован в массив

Решение зависит от используемой вами версии PHP. По крайней мере, есть два решения:

Сначала (новые версии PHP)

Как сказал @JosepAlsina, прежде всего лучшее, а также кратчайшее решение – использовать array_column следующим образом:

 $catIds = array_column($objects, 'id'); 

Примечание. Для итерации array содержащего \stdClass es, как используется в вопросе, возможно только с версиями PHP >= 7.0 . Но при использовании array содержащего array s, вы можете сделать то же самое с PHP >= 5.5 .

Второй (старые версии PHP)

@Greg сказал в более ранних версиях PHP, можно сделать следующее:

 $catIds = array_map(create_function('$o', 'return $o->id;'), $objects); 

Но будьте осторожны: в новых версиях PHP >= 5.3.0 лучше использовать Closure s, например:

 $catIds = array_map(function($o) { return $o->id; }, $objects); 

Разница

Первое решение создает новую функцию и помещает ее в вашу оперативную память. По какой-то причине сборщик мусора не удаляет уже созданный и уже вызванный экземпляр функции из памяти. И в следующий раз, когда вызывается этот код, эта же функция будет создана снова. Такое поведение медленно заполняет вашу память …

Оба примера с выходом памяти для их сравнения:

ПЛОХО

 while (true) { $objects = array_map(create_function('$o', 'return $o->id;'), $objects); echo memory_get_usage() . "\n"; sleep(1); } 4235616 4236600 4237560 4238520 ... 

ХОРОШО

 while (true) { $objects = array_map(function($o) { return $o->id; }, $objects); echo memory_get_usage() . "\n"; sleep(1); } 4235136 4235168 4235168 4235168 ... 

Это также можно обсудить здесь

Утечка памяти?! Правильно ли сборщик мусора, используя 'create_function' в 'array_map'?

 function extract_ids($cats){ $res = array(); foreach($cats as $k=>$v) { $res[]= $v->id; } return $res } 

и использовать его в одной строке :

 $ids = extract_ids($cats); 

Вы можете сделать это легко с uuzo goodies

 $result = array_map(Functions::extract()->id, $arr); 

или с массивами (из узе-лайтов)

 $result = Arrays::map($arr, Functions::extract()->id); 

Выезд: http://ouzo.readthedocs.org/ru/latest/utils/functions.html#extract

См. Также функциональное программирование с ouzo (я не могу опубликовать ссылку).

Встроенные петли в PHP быстрее интерпретируют циклы, поэтому на самом деле имеет смысл сделать это однострочным:

 $result = array(); array_walk($cats, create_function('$value, $key, &$result', '$result[] = $value->id;'), $result) 

КОД

 <?php # setup test array. $cats = array(); $cats[] = (object) array('id' => 15); $cats[] = (object) array('id' => 18); $cats[] = (object) array('id' => 23); function extract_ids($array = array()) { $ids = array(); foreach ($array as $object) { $ids[] = $object->id; } return $ids; } $cat_ids = extract_ids($cats); var_dump($cats); var_dump($cat_ids); ?> 

ВЫВОД

 # var_dump($cats); array(3) { [0]=> object(stdClass)#1 (1) { ["id"]=> int(15) } [1]=> object(stdClass)#2 (1) { ["id"]=> int(18) } [2]=> object(stdClass)#3 (1) { ["id"]=> int(23) } } # var_dump($cat_ids); array(3) { [0]=> int(15) [1]=> int(18) [2]=> int(23) } 

Я знаю, что он использует цикл, но это самый простой способ сделать это! И используя функцию, она все же заканчивается на одной строке.

  $object = new stdClass(); $object->id = 1; $object2 = new stdClass(); $object2->id = 2; $objects = [ $object, $object2 ]; $ids = array_map(function ($object) { /** @var YourEntity $object */ return $object->id; // Or even if you have public methods // return $object->getId() }, $objects); 

Выход : [1, 2]