PHP – 从一个对象数组中提取一个属性

我有一个猫对象的数组:

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

我想在1行(不是一个函数,也不是一个循环)提取一个猫的ID数组。

我正在考虑使用create_function array_walk ,但我不知道如何去做。

任何想法?

你可以使用array_map()函数。
这应该做到这一点:

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

如果你有PHP 5.5或更高版本 ,最好的方法是使用内置函数array_column()

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

但儿子必须是一个数组或转换为一个数组

解决scheme取决于您正在使用的PHP版本。 至less有2个解决scheme:

第一(较新的PHP版本)

正如@JosepAlsina所说,最好的也是最短的解决scheme是使用array_column如下:

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

注意:对于在问题中使用的包含\stdClass es的array ,只能在PHP版本>= 7.0情况下进行迭代。 但是,当使用包含array您可以执行相同的操作,因为PHP >= 5.5

第二(旧的PHP版本)

@Greg在旧的PHP版本中表示可以做以下事情:

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

但要小心:在更新的PHP版本>= 5.3.0情况下,最好使用Closure ,如下所示:

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

区别

第一个解决scheme创build一个新的function,并把它放到你的RAM中。 垃圾收集器不会因为某些原因而删除已经创build并已经调用的函数实例。 下一次调用这个代码时,会再次创build相同的函数。 这种行为缓慢地填满你的记忆…

这两个例子与记忆输出比较他们:

 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 ... 

这也可以在这里讨论

内存泄漏?! 在'array_map'中使用'create_function'时,垃圾收集器是否正确?

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

在一行中使用它:

 $ids = extract_ids($cats); 

你可以很容易地与ouzo好吃的东西

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

或与arrays(从ouzo好吃的东西)

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

请查阅: http : //ouzo.readthedocs.org/en/latest/utils/functions.html#extract

另请参阅function编程ouzo(我不能发布链接)。

PHP中的内build循环比解释循环更快,所以实际上这是一个单线程的意义:

 $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); ?> 

OUTPUT

 # 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]