PHP-从对象数组中提取属性

我找到了一系列猫的物品:

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

并且我想在一行中提取一个 cat ID 数组(不是函数也不是循环)。

我一直在考虑使用 array_walkcreate_function,但我不知道如何做到这一点。

知道吗?

160672 次浏览
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()。强烈建议不要依赖这个函数。

您可以使用 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 7.2.0开始就不赞成使用 create_function()。强烈建议不要依赖这个函数。

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():

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

但是子必须是一个数组或者转换成一个数组

解决方案取决于您使用的 PHP 版本。至少有两种解决方案:

第一(较新的 PHP 版本)

正如@JosepAlsina 之前所说,最好也是最短的解决方案是使用 array_column,如下所示:

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

注意: 要迭代问题中使用的包含 \stdClasses 的 array,只能使用 PHP 版本的 >= 7.0。但是当使用包含 arrayarray时,您可以从 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);


区别在于

第一个解决方案创建一个新函数并将其放入 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');