'PHP find an array item by a nested key [closed]
I have a PHP array and I need to find an item based on a key within the tlp_queue_manager_schedulers object, I tried doing array_search but this returned false, I also tried combining this method with array_column:
[
{
"tlp_queue_manager_schedulers":{
"id":"1",
"token":"ABC"
},
"0":{
"num":"1"
}
},
{
"tlp_queue_manager_schedulers":{
"id":"3",
"token":"cron-3"
},
"0":{
"num":"2"
}
},
{
"tlp_queue_manager_schedulers":{
"id":"4",
"token":"CronA75nvAgjsm8b"
},
"0":{
"num":"3"
}
},
{
"tlp_queue_manager_schedulers":{
"id":"2",
"token":"XYZ"
},
"0":{
"num":"4"
}
}
]
For example, I need to return the array item where the id key within tlp_queue_manager_schedulers matches 3, this should then return:
{
"tlp_queue_manager_schedulers":{
"id":"3",
"token":"cron-3"
},
"0":{
"num":"2"
}
}
Solution 1:[1]
Good ol' foreach loop. Nothing beats a foreach loop:
$matchingObject = null;
foreach($array as $obj)
{
if($obj->tlp_queue_manager_schedulers->id == "3")
{
$matchingObject = $obj;
break;
}
}
Solution 2:[2]
While the foreach loop by @Quasipickle would also be my staple fix, since we have a "brevity challenge" vs. Javascript's array.find() method, here's a PHP one-liner with array_filter:
$matches = array_filter($data,
fn($row) => $row['tlp_queue_manager_schedulers']['id'] == '3'
);
With the sample data given, this returns:
array(1) {
[1] · array(2) {
["tlp_queue_manager_schedulers"] · array(2) {
["id"] · string(1) "3"
["token"] · string(6) "cron-3"
}
[0] · array(1) {
["num"] · string(1) "2"
}
}
}
Note that this will return an array with all items matching the criteria (retaining original indexes). If no matches are found, an empty array is returned. If you're only interested in the first match, then $match = current($matches); (no matches: false) or $match = array_shift($matches); (no matches: null) will give you that.
If you have a large dataset and only care about finding the first match item, then foreach with a break after match is found (or alternatively return if your loop is inside a helper function) will potentially save you lots of redundant cycles, since array_filter will check the whole array 'til the end. (The difference will be inconsequential for small datasets).
P.S. In case you're wondering why array_search won't work: It only looks through array values, you can't specify a key to check. Even if you first used array_column, your column would still be an associative array. You could accomplish this with those functions and some level of trickery, however it'd be a long and convoluted solution... Better keep it simple and clean.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
