Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php, check if object with property = value exists in array of objects

Tags:

arrays

object

php

I think I could do this with a foreach loop like this:

 foreach ($haystack as $item)
       if (isset($item->$needle_field) && $item->$needle_field == $needle)
            return true;
 } 

but i was wandering if it could be done without a loop?

something like:

  if(in_array($item->$needle_field == $needle,$haystack)
            return true;
like image 725
andrew Avatar asked Jan 13 '23 10:01

andrew


1 Answers

Yes, in modern PHP you can determine if a specific object property contains a specific value without a classic loop by combining the forces of array_column() (which has evolved to also handle arrays of objects) and in_array().

Code: (Demo)

$objects = [
    (object)['cats' => 2],
    (object)['dogs' => 2],
    (object)['fish' => 10],
    (object)['birds' => 1],
];

$needleField = 'cats';
$needleValue = 2;

var_export(
    in_array($needleValue, array_column($objects, $needleField))
);
// output: true

The advantage of this technique is the obviously concise syntax. This is a perfectly acceptable approach for relatively small volumes of data.

A possible disadvantage to this technique is that array_column() will be generating a new array of all of values that relate to the $needleField.

In my above demo, array_column() will only generate a single-element array because there is only one cats property in all of the objects. If we were processing a relatively large volume of data, then it would be inefficient to bother collecting all of the qualifying cats values and then run in_array() when only one match is necessary to return true.

For "large" volumes of data where performance is a primary criterion for script design, a classic foreach loop would be a better choice and as soon as an object satisfies the rules, then the loop should be halted via return or break.

Code: (Demo)

function hasPropertyValue(array $objects, $property, $value): bool {
    foreach ($objects as $object) {
        if (property_exists($object, $property) && $object->{$property} === $value) {
            return true;
        }
    }
    return false;
}
var_export(
    hasPropertyValue($objects, $needleField, $needleValue)
);
like image 89
mickmackusa Avatar answered Jan 26 '23 13:01

mickmackusa