Filter an array of objects by a flat array

Viewed 72

I have this multidimensional array $currencies:

$currencies = array ( 
    0 => (object) array( 'name' => 'algo', 'fullName' => 'Algorand'), 
    1 => (object) array( 'name' => 'ardr', 'fullName' => 'Ardor'), 
    2 => (object) array( 'name' => 'eth', 'fullName' => 'Eth')
);

And I want to keep only the objects with a name that is in this array:

$filter = ["eth", "algo"];

I did this, but it doesn't work.

$currenciesFiltered = array_filter(
    $currencies,
    function ($value) use ($filter) {
        return in_array($value['name'], $filter);
    }
);

Where is my mistake?

2 Answers

According to the error output:

Uncaught Error: Cannot use object of type stdClass as array in [...][...]:13

You are casting the array to an object, but then trying to use it as an array later. When you remove the (object) casting, it works just as you are expecting.

If you must cast to an object, do it after the filter.

PHP already has native, optimized functions to compare/filter data from two iterable datasets.

array_uintersect(), in this case is perfect for filtering based on value.

Because the source array(s) that populate the $a and $b variable during iteration cannot be predicted, each attempt to access data must fallback to the alternate array's data.

Because only the $currencies array contains rows of objects, check for a name property inside the callback. If the property does not exist, you know that the accessible value belongs to the flat $filter array.

Code: (Demo)

var_export(
    array_uintersect(
        $currencies,
        $filter,
        fn($a, $b) =>
            ($a->name ?? $a)
            <=>
            ($b->name ?? $b)
    )
);

Output:

array (
  0 => 
  (object) array(
     'name' => 'algo',
     'fullName' => 'Algorand',
  ),
  2 => 
  (object) array(
     'name' => 'eth',
     'fullName' => 'Eth',
  ),
)
Related