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