2011-01-20 8 views
95

la matriz se ve como:PHP - Entrada por la propiedad objeto de una matriz de objetos

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

[1] => stdClass Object 
     (
      [ID] => 10957 
      [name] => Blah 
     ) 
... 

Y tengo una variable entera llamada $v.

¿Cómo podría seleccionar una entrada de matriz que tiene un objeto donde la propiedad 'ID' tiene el valor $v?

Respuesta

126

O itere la matriz, buscando el registro particular (ok en una búsqueda de única vez) o construya una hashmap usando otra matriz asociativa.

Para los primeros, algo como esto

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

Ver esta pregunta y respuestas posteriores para obtener más información sobre este último - Reference PHP array by multiple indexes

+3

configuración $ item to null no es necesario. – dAm2K

+0

verifique su primera línea de código. – dAm2K

+24

Vaya, ahí está :) Eso es en caso de que el elemento buscado no esté en la matriz. Alternativamente, puede usar 'isset ($ item)' pero prefiero inicializar las variables correctamente – Phil

16

que he encontrado solución más elegante here. Adaptado a la pregunta que puede parecer:

$neededObject = array_filter(
    $arrayOfObjects, 
    function ($e) { 
     return $e->id == $searchedValue; 
    } 
); 
+4

+1 pero 'array_filter' devuelve una matriz, y no se detendrá en el primer valor encontrado. –

+0

bueno, depende;) si tengo un conjunto de pocos elementos prefiero array_filter sobre loop hecho a mano, considerando que está construido en la función php. – YurkaTim

+4

No reconoce '$ searchedValue' dentro de la función. Pero afuera está. –

46

YurkamTim es correcto. Solo necesita una modificación: (Lo siento, no puedo comentar ahora).

Después de la función ($) necesita un puntero a la variable externa mediante "use (& $ searchedValue)" y luego puede acceder a la variable externa. También puedes modificarlo.

$neededObject = array_filter(
    $arrayOfObjects, 
    function ($e) use (&$searchedValue) { 
     return $e->id == $searchedValue; 
    } 
); 
+2

Tiene razón acerca de la modificación y es una especie de método limpio , pero probé la velocidad en comparación con la iteración a través del objeto: usted mismo, porque al igual que @phil señalado, array_filter también lo está haciendo, y este método tarda unas cinco veces más. Mi objeto de prueba no es grande, por lo que podría empeorar. – Nicolai

+4

El '&' no es necesario cuando se importa '$ searchedValue' en el ámbito de cierre. El '&' se usa para crear una referencia que solo es necesaria si '$ searchedValue' se ha modificado dentro del cierre. –

+0

Eso es genial. No sabía que PHP podría hacer cosas como esa. ¡Pensé que usar 'global' era lo único que era compartir datos en funciones! Pero es una pena si esto es realmente lento. :( – NoOne

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

Uso de la manera que quería sería algo así como:

ArrayUtils::objArraySearch($array,'ID',$v); 
1

Hice esto con algún tipo de mapa de teclas de Java. Si lo hace, no necesita recorrer su matriz de objetos todo el tiempo.

<?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']; 

de salida:

array (size=2) 
    0 => 
    object(stdClass)[1] 
     public 'id' => int 123 
     public 'name' => string 'Henk' (length=4) 
     public 'age' => int 65 
    1 => 
    object(stdClass)[2] 
     public 'id' => int 273 
     public 'name' => string 'Koos' (length=4) 
     public 'age' => int 25 
array (size=2) 
    123 => string 'Henk' (length=4) 
    273 => string 'Koos' (length=4) 
Henk 
+0

¡Ah, reindexando la matriz por identificación! Hago esto comúnmente y hace las cosas más agradables. – Kzqai

2

a veces como el uso de la función array_reduce() para llevar a cabo la búsqueda. Es similar a array_filter() pero no afecta a la matriz buscada, lo que le permite llevar a cabo múltiples búsquedas en la misma matriz de objetos.

$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): "; 
} 
+1

Tiene un error tipográfico dentro de su condicional donde está agregando tot results_array. Debería ser esto: '' 'if ($ current_item-> someProperty == $ needle) { $ result_array [] = $ current_item; }' ' – adrum

+0

Ajustado. Gracias @adrum! – yuvilio

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

echo array_search(1, array_column($arr, 'ID')); // prints 0 (!== false) 
2

La fijación de un pequeño error de la @YurkaTim, su trabajo solución para mí, pero añadiendo use:

Para utilizar $searchedValue, dentro de la función, una solución puede ser use ($searchedValue) después de los parámetros de función function ($e) HERE.

la función array_filter solamente el retorno de la $neededObject el caso de la condición de retorno es true

Si $searchedValue es una cadena o un entero:

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

Si $searchedValue es matriz donde necesitamos comprobar con una lista:

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

Usando array_column volver a indexar ahorrará tiempo si es necesario encontrar varias veces:

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

, entonces puede simplemente $lookup[$id] a voluntad.

Cuestiones relacionadas