PHP - 从对象数组中按对象属性查找条目

Ale*_*lex 148 php arrays object

该数组看起来像:

[0] => stdClass Object
        (
            [ID] => 420
            [name] => Mary
         )

[1] => stdClass Object
        (
            [ID] => 10957
            [name] => Blah
         )
...
Run Code Online (Sandbox Code Playgroud)

我有一个名为的整数变量$v.

如何选择具有"ID"属性具有ID值的对象的数组条目?

Phi*_*hil 168

您可以迭代数组,搜索特定记录(仅在一次搜索中确定)或使用另一个关联数组构建哈希映射.

对于前者,这样的事情

$item = null;
foreach($array as $struct) {
    if ($v == $struct->ID) {
        $item = $struct;
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

有关后者的更多信息,请参阅此问题和后续答案 - 通过多个索引引用PHP数组

  • 哎呀,就是:)这就是所寻找的项目不在数组中.或者,您可以使用`isset($ item)`但我更喜欢正确初始化变量 (29认同)
  • 如果你是downvote,请发表评论 (5认同)
  • 不需要将$ item设置为null. (3认同)
  • 对于那些将键值设置为字符串的人,请使用`if($ v == $ struct ["ID"]){...` (3认同)

Dan*_*rdt 63

YurkamTim是对的.它只需要修改:(抱歉,我现在无法发表评论).

在函数($)之后,您需要通过"use(&$ searchingValue)"指向外部变量,然后您可以访问外部变量.你也可以修改它.

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use (&$searchedValue) {
        return $e->id == $searchedValue;
    }
);
Run Code Online (Sandbox Code Playgroud)

  • TS要求输入一个条目,此代码返回一个数组. (8认同)
  • 将`$ searchingValue`导入闭包范围时,不需要`&`.`&`用于创建一个引用,只有在闭包内修改了`$ searchingValue`时才需要它. (7认同)
  • 你是正确的修改,它是一种简洁的方法,但我测试速度相比迭代对象 - 你自己,因为像@phil指出,array_filter也这样做 - 这个方法大约需要五个时间更长.我的测试对象不是很大,所以可能会变得更糟. (2认同)

Tim*_*Tim 32

$arr = [
  [
    'ID' => 1
  ]
];

echo array_search(1, array_column($arr, 'ID')); // prints 0 (!== false)
Run Code Online (Sandbox Code Playgroud)

  • 非常优雅的解决方案。也适用于 PHP 7 中的对象数组。对于 PHP 5: array_search($object->id, array_map(function($object) { return $object->id; }, $objects)); 对于 PHP 7: array_search($object->id, array_column($objects, 'id')); (3认同)
  • 这不是首选答案,因为 op 要求提供对象数组,而此答案仅处理纯数组。 (3认同)
  • 不知道为什么这不是首选答案。是因为您要调用两个函数吗? (2认同)
  • 我想我参加聚会已经太晚了;)它的不足和可读性,没有任何循环和中断将使它合理。但还没有对其进行基准测试。PHP 中有很多选项可以实现相同的目的。 (2认同)
  • 那是不正确的。此代码处理对象数组/非平面数组 (2认同)

Yur*_*Tim 26

我在这里找到了更优雅的解决方案.适应问题可能如下:

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) {
        return $e->id == $searchedValue;
    }
);
Run Code Online (Sandbox Code Playgroud)

  • +1但是`array_filter`返回一个数组,并且不会停在找到的第一个值. (9认同)
  • 它无法识别函数内的`$ searchingValue`.但除此之外. (4认同)
  • 对于初学者来说,这段代码不起作用,因为`$ searchingValue`在闭包范围之外.其次,您如何看待这些数组方法的工作原理?它们都在内部循环遍历数组 (4认同)
  • 使用`$ searchedValue`需要写`function($ e)use($ searchedValue){` (2认同)

Mus*_*ful 12

如果需要多次查找,使用array_column重新索引将节省时间:

$lookup = array_column($arr, NULL, 'id');   // re-index by 'id'
Run Code Online (Sandbox Code Playgroud)

然后你可以随意$lookup[$id].

  • 这是最令人惊奇的答案,即使它不是最直观的...... (4认同)

Pab*_*eco 9

class ArrayUtils
{
    public static function objArraySearch($array, $index, $value)
    {
        foreach($array as $arrayInf) {
            if($arrayInf->{$index} == $value) {
                return $arrayInf;
            }
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用您想要的方式将是这样的:

ArrayUtils::objArraySearch($array,'ID',$v);
Run Code Online (Sandbox Code Playgroud)


Jos*_*tes 7

解决了@YurkaTim的一个小错误,您的解决方案对我有用,但是添加了use

$searchedValue在函数内部使用,一种解决方案可以use ($searchedValue)在函数参数之后function ($e) HERE

array_filter函数仅$neededObject在条件为return时返回true

如果$searchedValue是字符串或整数:

$searchedValue = 123456; // Value to search.
$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use ($searchedValue) {
        return $e->id == $searchedValue;
    }
);
var_dump($neededObject); // To see the output
Run Code Online (Sandbox Code Playgroud)

如果$searchedValue是数组,我们需要检查列表:

$searchedValue = array( 1, 5 ); // Value to search.
$neededObject  = array_filter(
    $arrayOfObjects,
    function ( $e ) use ( $searchedValue ) {
        return in_array( $e->term_id, $searchedValue );
    }
);
var_dump($neededObject); // To see the output
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 5

尝试

$entry = current(array_filter($array, function($e) use($v){ return $e->ID==$v; }));
Run Code Online (Sandbox Code Playgroud)

这里的工作示例