Php 如何从对象数组中按对象属性查找条目?

Php 如何从对象数组中按对象属性查找条目?,php,arrays,object,Php,Arrays,Object,该数组看起来像: [0] => stdClass Object ( [ID] => 420 [name] => Mary ) [1] => stdClass Object ( [ID] => 10957 [name] => Blah ) ... 我有一个名为$v的整数变量 我如何选择一个数组项,

该数组看起来像:

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

[1] => stdClass Object
        (
            [ID] => 10957
            [name] => Blah
         )
...
我有一个名为
$v
的整数变量


我如何选择一个数组项,该数组项包含一个对象,而
ID
属性具有
$v
值?

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

对于前者,类似这样的情况

$item = null;
foreach($array as $struct) {
    if ($v == $struct->ID) {
        $item = $struct;
        break;
    }
}

有关后者的更多信息,请参见此问题和后续答案-

我找到了更优雅的解决方案。适用于以下问题:

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use ($searchedValue) {
        return $e->id == $searchedValue;
    }
);
这是对的。它只需要修改一下:

在函数($)之后,需要通过“use(&$searchedValue)”指向外部变量的指针,然后才能访问外部变量。你也可以修改它

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use (&$searchedValue) {
        return $e->id == $searchedValue;
    }
);
以您想要的方式使用它可能是:

ArrayUtils::objArraySearch($array,'ID',$v);
$i = array_search(1, array_column($arr, 'ID'));
$element = ($i !== false ? $arr[$i] : null);

我是用某种Java键映射实现的。 如果这样做,就不需要每次都在对象数组上循环

<?php

//This is your array with objects
$object1 = (object) array('id'=>123,'name'=>'Henk','age'=>65);
$object2 = (object) array('id'=>273,'name'=>'Koos','age'=>25);
$object3 = (object) array('id'=>685,'name'=>'Bram','age'=>75);
$firstArray = Array($object1,$object2);
var_dump($firstArray);

//create a new array
$secondArray = Array();
//loop over all objects
foreach($firstArray as $value){
    //fill second        key          value
    $secondArray[$value->id] = $value->name;
}

var_dump($secondArray);

echo $secondArray['123'];

我有时喜欢使用该功能来执行搜索。它类似于array_filter(),但不影响搜索的数组,允许对同一对象数组执行多个搜索

$haystack = array($obj1, $obj2, ...); //some array of objects
$needle = 'looking for me?'; //the value of the object's property we want to find

//carry out the search
$search_results_array = array_reduce(
  $haystack,

  function($result_array, $current_item) use ($needle){
      //Found the an object that meets criteria? Add it to the the result array 
      if ($current_item->someProperty == $needle){
          $result_array[] = $current_item;
      }
      return $result_array;
  },
  array() //initially the array is empty (i.e.: item not found)
);

//report whether objects found
if (count($search_results_array) > 0){
  echo "found object(s): ";
  print_r($search_results_array[0]); //sample object found
} else {
  echo "did not find object(s): ";
}
上面的代码回显匹配元素的索引,如果没有,则回显
false

要获取相应的元素,请执行以下操作:

ArrayUtils::objArraySearch($array,'ID',$v);
$i = array_search(1, array_column($arr, 'ID'));
$element = ($i !== false ? $arr[$i] : null);

既适用于数组,也适用于对象数组。

修复了的一个小错误,您的解决方案对我有效,但添加了
use

$haystack = array($obj1, $obj2, ...); //some array of objects
$needle = 'looking for me?'; //the value of the object's property we want to find

//carry out the search
$search_results_array = array_reduce(
  $haystack,

  function($result_array, $current_item) use ($needle){
      //Found the an object that meets criteria? Add it to the the result array 
      if ($current_item->someProperty == $needle){
          $result_array[] = $current_item;
      }
      return $result_array;
  },
  array() //initially the array is empty (i.e.: item not found)
);

//report whether objects found
if (count($search_results_array) > 0){
  echo "found object(s): ";
  print_r($search_results_array[0]); //sample object found
} else {
  echo "did not find object(s): ";
}

要使用
$searchedValue
,在函数内部,可以在函数参数
函数($e)之后使用
use($searchedValue)

如果返回条件为
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
$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
如果
$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
$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
如果您需要查找多次,使用重新索引将节省时间:

$lookup = array_column($arr, NULL, 'id');   // re-index by 'id'

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

我在这里发布了我使用快速二进制搜索算法有效解决这个问题的方法:

我不想抄袭同样的答案。其他人的提问略有不同,但答案是一样的。

试试看

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

工作示例

立即获取第一个值的方法:

$neededObject = array_reduce(
    $arrayOfObjects,
    function ($result, $item) use ($searchedValue) {
        return $item->id == $searchedValue ? $item : $result;
    }
);

我通过用ID键控数组解决了这个问题。在这种情况下,ID就是您要寻找的,这样做更简单,也可能更快

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

[10957] => stdClass Object
        (
            [name] => Blah
         )
...
现在我可以直接寻址阵列:

$array[$v]->name = ...
或者,如果我想验证是否存在ID:

if (array_key_exists($v, $array)) { ...

不需要将$item设置为null。哦,就是这样:),以防搜索的项不在数组中。或者,您可以使用
isset($item)
,但对于那些键值设置为strings的人,如果($v==$struct[“ID”]),我更喜欢正确初始化变量{…
+1但是
array\u filter
返回一个数组,并且不会在找到的第一个值时停止。它不识别函数内部的
$searchedValue
。但是在函数外部。对于初学者来说,此代码不工作,因为
$searchedValue
在闭包范围之外。其次,您认为这些数组方法如何工作?它们是阵列内部的所有循环在多核时,不幸的是,在其他编程环境中,这可以并行处理,上面的循环不一定要使用
$searchedValue
需要写入
函数($e)使用($searchedValue){
您对修改的看法是正确的,这是一种简洁的方法,但我测试了与迭代对象(您自己)相比的速度,因为正如@phil指出的,array_filter也在这样做,而且这种方法花费的时间大约是原来的五倍。我的测试对象不是很大,所以可能会变得更糟。
&
在将
$searchedValue
导入闭包范围时不需要。
&
用于创建引用,只有在闭包内部修改了
$searchedValue
时才需要引用。这很酷。我不知道PHP可以做类似的事情。我认为使用
全局
是在中共享数据的唯一方法函数!但如果这确实很慢,那就很遗憾了。:(TS要求输入一个条目,此代码返回一个数组。已更新为包含
use($searchedValue)
。正如StefangeRig在其评论中所说,您不需要
&
使用(&$searchedValue)
除非您需要修改$searchedValue.Ah,否则请按id重新索引数组!我通常会这样做,这会让事情变得更好。只需一行代码,使用
array\u column
重新索引即可完成此操作。从PHP5.5开始,您的条件中有一个输入错误,将结果添加到数组中。应该是这样:
 如果($current\u item->someProperty=$needle){$result\u array[]=$current\u item;}
已调整。感谢@adrum!Re“它类似于array\u filter(),但不影响搜索的数组,允许您执行多个搜索”:您似乎误以为
array\u filter
会修改原始数组。事实并非如此。您创建$result\u数组的功能正是array\u filter所做的!这是使用
array\u reduce
的有效方法;我认为在任何情况下此答案都是有用的-只需使用AndreyP的答案。如果您ant在第一项停止,然后编写一个在第一项停止的函数!!不确定为什么这不是首选答案。是因为你调用了两个函数吗?我想我来不及参加聚会了;)它的不足和可读性,没有任何循环和中断,这将使它合理。但还没有对它进行基准测试。在PHP中有很多选项可以实现同样的效果。非常优雅的解决方案