我找到了一系列猫的物品:
$cats = Array ( [0] => stdClass Object ( [id] => 15 ), [1] => stdClass Object ( [id] => 18 ), [2] => stdClass Object ( [id] => 23 ) )
并且我想在一行中提取一个 cat ID 数组(不是函数也不是循环)。
我一直在考虑使用 array_walk和 create_function,但我不知道如何做到这一点。
array_walk
create_function
知道吗?
function extract_ids($cats){ $res = array(); foreach($cats as $k=>$v) { $res[]= $v->id; } return $res }
并使用它 排成一行:
$ids = extract_ids($cats);
警告 从 PHP 7.2.0开始就不赞成使用 create_function()。强烈建议不要依赖这个函数。
create_function()
您可以使用 array_map()函数。 这个应该可以:
array_map()
$catIds = array_map(create_function('$o', 'return $o->id;'), $objects);
正如@Relequestual 下面所写的,该函数现在直接集成到 array _ map 中。新版本的解决方案是这样的:
$catIds = array_map(function($o) { return $o->id;}, $objects);
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) }
我知道它使用一个循环,但这是最简单的方式做到这一点!使用一个函数,它仍然只有一行。
如果你有 PHP 5.5或更高版本,最好的方法是使用内置的函数 array_column():
array_column()
$idCats = array_column($cats, 'id');
但是子必须是一个数组或者转换成一个数组
解决方案取决于您使用的 PHP 版本。至少有两种解决方案:
正如@JosepAlsina 之前所说,最好也是最短的解决方案是使用 array_column,如下所示:
array_column
$catIds = array_column($objects, 'id');
注意: 要迭代问题中使用的包含 \stdClasses 的 array,只能使用 PHP 版本的 >= 7.0。但是当使用包含 array的 array时,您可以从 PHP >= 5.5开始做同样的事情。
\stdClass
array
>= 7.0
>= 5.5
@ Greg 说在旧的 PHP 版本中可以做到以下几点:
但是要注意: 在较新的 PHP 版本 >= 5.3.0中,最好使用 Closure,如下所示:
>= 5.3.0
Closure
$catIds = array_map(function($o) { return $o->id; }, $objects);
第一个解决方案创建一个新函数并将其放入 RAM 中。由于某种原因,垃圾回收器不会将已创建并已调用的函数实例从内存中删除。而且不管事实如何,已创建的函数实例永远不能再次调用,因为我们没有指向它的指针。下次调用此代码时,将再次创建相同的函数。这种行为会慢慢填满你的记忆。
这两个例子都有内存输出来比较它们:
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 ...
内存泄漏? ! 垃圾收集器在使用 array _ map 内的 create _ function 时是否正确?
你可以很容易地做到这一点与 茴香酒
$result = array_map(Functions::extract()->id, $arr);
或与数组(从茴香酒好吃)
$result = Arrays::map($arr, Functions::extract()->id);
看看 http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract
也可以参见使用 ouzo 的函数式编程(我不能发布链接)。
$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]
// $array that contain records and id is what we want to fetch a $ids = array_column($array, 'id');
从 Php v7.2.0开始就不推荐使用 create_function()函数,
function getObjectID($obj){ return $obj->id; } $IDs = array_map('getObjectID' , $array_of_object);
或者,您可以使用 array_column()函数,该函数从输入的单个列中返回值,该列由 column _ key 标识。或者,可以提供 index _ key 来根据输入数组 index _ key 列中的值对返回数组中的值进行索引。可以使用给定的 array _ column,
$IDs = array_column($array_of_object , 'id');