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

PHP-从对象数组中提取属性,php,Php,我有一系列猫类物品: $cats = Array ( [0] => stdClass Object ( [id] => 15 ), [1] => stdClass Object ( [id] => 18 ), [2] => stdClass Object

我有一系列猫类物品:

$cats = Array
    (
        [0] => stdClass Object
            (
                [id] => 15
            ),
        [1] => stdClass Object
            (
                [id] => 18
            ),
        [2] => stdClass Object
            (
                [id] => 23
            )
)
我想在一行中提取一组猫的ID(不是函数也不是循环)

我正在考虑使用
array\u walk
create\u函数
,但我不知道怎么做

有什么想法吗

function extract_ids($cats){
    $res = array();
    foreach($cats as $k=>$v) {
        $res[]= $v->id;
    }
    return $res
}
并在一行中使用它:

警告
create_function()
自PHP 7.2.0起已被弃用。非常不鼓励依赖此功能

您可以使用该功能。
这应该做到:

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

正如@Relequestual在下面写到的,该函数现在直接集成到数组映射中。新版本的解决方案如下所示:

$catIds = array_map(function($o) { return $o->id;}, $objects);
警告
create_function()
自PHP 7.2.0起已被弃用。非常不鼓励依赖此功能

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

?>

我知道它使用循环,但这是最简单的方法!使用一个函数,它仍然会在一行中结束。

如果您使用的是PHP5.5或更高版本,最好的方法是使用内置函数
array\u column()


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

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

第一个(更新的PHP版本) 正如@JosepAlsina之前所说的,最好也是最短的解决方案是使用
array\u column
,如下所示:

$catIds = array_column($objects, 'id');
$catIds = array_map(create_function('$o', 'return $o->id;'), $objects);
注意: 对于迭代包含问题中使用的
\stdClass
es的
数组
,只有PHP版本
>=7.0
才可能。但是,当使用包含
数组的
数组时,您也可以这样做,因为PHP
=5.5

第二(旧的PHP版本) @格雷格说,在较旧的PHP版本中,可以执行以下操作:

$catIds = array_column($objects, 'id');
$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);

区别 第一个解决方案创建一个新函数并将其放入RAM中。由于某种原因,垃圾收集器不会从内存中删除已经创建和调用的函数实例。不管事实如何,创建的函数实例永远不能被再次调用,因为我们没有它的指针。下次调用此代码时,将再次创建相同的函数。这种行为会慢慢填满你的记忆

这两个示例都有内存输出以进行比较:

坏的 好

这也可以在这里讨论

您可以轻松地使用

或使用阵列(来自ouzo goodies)

退房:

另请参见ouzo的函数式编程(我无法发布链接)

输出:[1,2]

从php v7.2.0开始,不推荐使用
create_function()
函数。您可以使用给定的
数组映射()

// $array that contain records and id is what we want to fetch a
$ids = array_column($array, 'id');
函数getObjectID($obj){ 返回$obj->id; } $IDs=array\u映射('getObjectID',$array\u of\u对象);
或者,您可以使用
array\u column()
函数,该函数返回由column\u键标识的单个输入列的值。可选地,可以提供索引键,以通过来自输入数组的索引键列的值来索引返回数组中的值。可以使用给定的数组_列

$IDs=array_列($array_of_object,'id');

我不想使用循环,因为我希望能够在一行中分配结果:$cats_id=myfunction($cats);/*应该返回数组(15、18、23)*/谢谢SilentGhost,但我的问题是只需一个命令就可以得到$res,而不是使用循环…这有什么区别?这是最直截了当的。您可能会使用像
array\u walk
@deceze这样的东西来使用更多的行,一个优雅、简单和简洁的解决方案看起来更好——特别是对于像这个操作这样可以解释的东西(例如,这不是需要大量空间和注释的自定义逻辑)。对我来说,这是一个很大的不同。这是正确的解决方案,并将导致每个即将到来的维护者都是“wtf”d:d这个解决方案唯一让我不喜欢的是使用create_函数。你可以使用lambda函数,但没有多少人会在我们开始之前运行PHP5.3:
$project_names=array_map(函数($project){返回$project->name;},$projects)
然而,值得注意的是,这种方式可能会慢2.5倍/内存密集。我发现,每次使用
create\u function
创建函数时,内存都在增长。如果编写一个具有无限循环的程序,并使用
create\u function
调用
array\u map
,您将始终得到它
内存不足…
有时出错。因此不要使用
create\u函数
array\u映射(函数($o){return$o->id;},$objects)
我不明白为什么人们不选择这样简单的解决方案。如果你问我,这样做似乎是合乎逻辑的。这种解决方案没有回答这个问题,因为,
array\u column
根本不能与
对象的
数组
一起工作。因为PHP7.0.0是可能的:它只有在对象正确的情况下才能工作ty具有公共访问权限。虽然我使用的是PHP7.2,但如果您使用的是命名空间类对象,并且返回空数组,则解决方案似乎不起作用。您能发布一个漏洞吗?一个简短的片段以更好地理解您的上下文吗?例如,请参见这里,我有dropbox API SDK返回的模型对象列表,以及当我们尝试使用
array\u column
在此数组上,它始终返回空白,而snippet工作正常,两者都具有受保护的属性,仅可在第二个snippet中访问。除了命名空间之外,我找不到任何其他原因。当我在中写入
对象时
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
...
$result = array_map(Functions::extract()->id, $arr);
$result = Arrays::map($arr, Functions::extract()->id);
    $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);
// $array that contain records and id is what we want to fetch a
$ids = array_column($array, 'id');