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

时间:2009-07-13 11:42:47

标签: php

我有一系列猫对象:

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

我想在一行中提取一系列猫的ID(不是函数也不是循环)。

我在考虑将array_walkcreate_function一起使用,但我不知道该怎么做。

有什么想法吗?

10 个答案:

答案 0 :(得分:146)

您可以使用array_map()功能 这应该这样做:

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

答案 1 :(得分:100)

如果你有 PHP 5.5或更高版本,最好的方法是使用内置函数array_column()

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

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

答案 2 :(得分:71)

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

第一个(较新的PHP版本)

正如@JosepAlsina所说,在最佳和最短的解决方案之前使用array_column如下:

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

注意: 对于迭代问题中使用的包含array es的\stdClass,只能使用PHP版本>= 7.0。但是,当使用包含array的{​​{1}}时,您可以执行与PHP array相同的操作。

第二个(较旧的PHP版本)

@Greg在较旧的PHP版本中表示可以执行以下操作:

>= 5.5

但要注意:在较新的PHP版本$catIds = array_map(create_function('$o', 'return $o->id;'), $objects); 中,最好使用>= 5.3.0 s,如下所示:

Closure


差异

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

两个带内存输出的例子都比较它们:

BAD

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

GOOD

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


这也可以在这里讨论

Memory leak?! Is Garbage Collector doing right when using 'create_function' within 'array_map'?

答案 3 :(得分:4)

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

并在一行中使用

$ids = extract_ids($cats);

答案 4 :(得分:3)

您可以使用ouzo goodies

轻松完成
$result = array_map(Functions::extract()->id, $arr);

或与阵列(来自ouzo goodies)

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

退房:http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract

另请参阅使用ouzo进行函数式编程(我无法发布链接)。

答案 5 :(得分:2)

PHP中的内置循环比解释循环更快,因此将这个循环变为单行实际上是有意义的:

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

答案 6 :(得分:2)

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

?>

<强>输出

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

我知道它使用循环,但这是最简单的方法!并且使用一个函数它仍然只能在一行上。

答案 7 :(得分:1)

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

答案 8 :(得分:0)

    $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]

答案 9 :(得分:0)

create_function() 函数自 php v7.2.0 起已被弃用。您可以按给出的方式使用 array_map()

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