简体   繁体   English

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

[英]PHP - Extracting a property from an array of objects

I've got an array of cats objects:我有一系列猫对象:

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

and I want to extract an array of cats' IDs in 1 line (not a function nor a loop).我想在一行中提取一组猫的 ID(不是函数也不是循环)。

I was thinking about using array_walk with create_function but I don't know how to do it.我正在考虑将array_walkcreate_function一起使用,但我不知道该怎么做。

Any idea?任何的想法?

If you have PHP 5.5 or later , the best way is to use the built in function array_column() :如果您有PHP 5.5 或更高版本,最好的方法是使用内置函数array_column()

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

But the son has to be an array or converted to an array但是儿子必须是数组或者转换成数组

Warning create_function() has been DEPRECATED as of PHP 7.2.0.警告create_function()自 PHP 7.2.0 起已弃用。 Relying on this function is highly discouraged.非常不鼓励依赖此功能。

You can use the array_map() function.您可以使用array_map()函数。
This should do it:这应该这样做:

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

As @Relequestual writes below, the function is now integrated directly in the array_map.正如@Relequestual 在下面所写,该函数现在直接集成在 array_map 中。 The new version of the solution looks like this:新版本的解决方案如下所示:

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

The solution depends on the PHP version you are using.解决方案取决于您使用的 PHP 版本。 At least there are 2 solutions:至少有2个解决方案:

First (Newer PHP versions)首先(较新的 PHP 版本)

As @JosepAlsina said before the best and also shortest solution is to use array_column as following:正如@JosepAlsina 之前所说,最好也是最短的解决方案是使用array_column如下:

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

Notice: For iterating an array containing \stdClass es as used in the question it is only possible with PHP versions >= 7.0 .注意:要迭代问题中使用的包含\stdClass es 的array ,只有 PHP 版本>= 7.0才有可能。 But when using an array containing array s you can do the same since PHP >= 5.5 .但是当使用包含arrayarray时,您可以从 PHP >= 5.5开始做同样的事情。

Second (Older PHP versions)第二(旧的 PHP 版本)

@Greg said in older PHP versions it is possible to do following: @Greg 说在较旧的 PHP 版本中可以执行以下操作:

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

But beware: In newer PHP versions >= 5.3.0 it is better to use Closure s, like followed:但要注意:在较新的 PHP 版本>= 5.3.0中,最好使用Closure s,如下所示:

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


The difference区别

First solution creates a new function and puts it into your RAM.第一个解决方案创建一个新函数并将其放入您的 RAM 中。 The garbage collector does not delete the already created and already called function instance out of memory for some reason.由于某种原因,垃圾收集器不会从内存中删除已创建和已调用的函数实例。 And that regardless of the fact, that the created function instance can never be called again, because we have no pointer for it.而且不管事实如何,创建的函数实例都不能再被调用,因为我们没有它的指针。 And the next time when this code is called, the same function will be created again.下次调用此代码时,将再次创建相同的函数。 This behavior slowly fills your memory...这种行为慢慢填满你的记忆……

Both examples with memory output to compare them:两个带有内存输出的例子来比较它们:

BAD坏的

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

GOOD好的

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

    echo memory_get_usage() . "\n";

    sleep(1);
}

// the output
4235136
4235168
4235168
4235168
...


This may also be discussed here这也可以在这里讨论

Memory leak?? 内存泄漏?? Is Garbage Collector doing right when using 'create_function' within 'array_map'? 在“array_map”中使用“create_function”时,垃圾收集器是否正确运行?

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

and use it in one line :在一行中使用它:

$ids = extract_ids($cats);

Warning create_function() has been DEPRECATED as of PHP 7.2.0.警告create_function()自 PHP 7.2.0 起已弃用。 Relying on this function is highly discouraged.非常不鼓励依赖此功能。

Builtin loops in PHP are faster then interpreted loops, so it actually makes sense to make this one a one-liner: PHP 中的内置循环比解释循环更快,因此将其设为单行循环实际上是有意义的:

$result = array();
array_walk($cats, create_function('$value, $key, &$result', '$result[] = $value->id;'), $result)

CODE代码

<?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)
}

I know its using a loop, but it's the simplest way to do it.我知道它使用循环,但这是最简单的方法。 And using a function it still ends up on a single line.并且使用一个函数它仍然在一行上结束。

You can do it easily with ouzo goodies你可以用茴香酒轻松做到这一点

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

or with Arrays (from ouzo goodies)或阵列(来自ouzo goodies)

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

Check out: http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract查看:http: //ouzo.readthedocs.org/en/latest/utils/functions.html#extract

See also functional programming with ouzo (I cannot post a link).另请参阅使用 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);

Output : [1, 2]输出:[1, 2]

// $array that contain records and id is what we want to fetch a
$ids = array_column($array, 'id');

The create_function() function is deprecated as of php v7.2.0 . create_function()函数从php v7.2.0 开始被弃用。 You can use the array_map() as given,您可以使用给定的array_map()

function getObjectID($obj){
    return $obj->id;
}

$IDs = array_map('getObjectID' , $array_of_object);

Alternatively, you can use array_column() function which returns the values from a single column of the input, identified by the column_key.或者,您可以使用array_column()函数,该函数从输入的单个列返回值,由 column_key 标识。 Optionally, an index_key may be provided to index the values in the returned array by the values from the index_key column of the input array.可选地,可以提供 index_key 以通过输入数组的 index_key 列中的值对返回数组中的值进行索引。 You can use the array_column as given,您可以使用给定的 array_column,

$IDs = array_column($array_of_object , 'id');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM