PHP-извлечение свойства из массива объектов
у меня есть массив объектов cats:
$cats = Array
(
[0] => stdClass Object
(
[id] => 15
),
[1] => stdClass Object
(
[id] => 18
),
[2] => stdClass Object
(
[id] => 23
)
)
и я хочу извлечь массив идентификаторов кошек в 1 строке (не функция и не цикл).
Я думал об использовании array_walk
С create_function
но я не знаю как это сделать.
есть идеи?
8 ответов:
можно использовать
array_map()
Если у вас в PHP 5.5 или более поздней версии лучший способ-использовать встроенную функцию
array_column()
:$idCats = array_column($cats, 'id');
но сын должен быть массивом или преобразован в массив
решение зависит от версии PHP, которую вы используете. По крайней мере есть 2 решения:
первый (новые версии 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); } // the output 4235616 4236600 4237560 4238520 ...
хороший
while (true) { $objects = array_map(function($o) { return $o->id; }, $objects); echo memory_get_usage() . "\n"; sleep(1); } // the output 4235136 4235168 4235168 4235168 ...
это также можно обсудить здесь
function extract_ids($cats){ $res = array(); foreach($cats as $k=>$v) { $res[]= $v->id; } return $res }
и использовать его в одну строку:
$ids = extract_ids($cats);
Вы можете сделать это легко с УЗО вкусности
$result = array_map(Functions::extract()->id, $arr);
или с массивами (из УЗО лакомства)
$result = Arrays::map($arr, Functions::extract()->id);
Проверьте:http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract
см. также функциональное программирование с УЗО (я не могу опубликовать ссылку).
встроенные циклы в 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]