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]