morteza mortezaie
morteza mortezaie

Reputation: 1564

Filter array of associative arrays with a dynamic associative array where all elements must be matched

I need to filter my indexed array of associative arrays using an associative that may have different combinations of elements and potentially a variable number of elements.

$users = [
    [
        "name" => "ali",
        "age" => 22,
        "score" => 12
    ],
    [
        "name" => "hasan",
        "age" => 32,
        "score" => 52
    ],
];

And

$filters = [
    "name" => "ali",
    "age" => 22
];

I need to filter the $users array dynamically depending on this $filters.

function filter($item)
{
    // i dont how what should write here
}
$filtered_users = array_filter($users, 'filter');

Upvotes: 0

Views: 876

Answers (2)

mickmackusa
mickmackusa

Reputation: 47991

For a concise, fully functional-style approach, check that there is no remaining, unmatched element in the $filters array while comparing each row. This approach will not break even if keys in $filters do not exist in the $users rows. (Demo)

var_export(
    array_filter(
        $users,
        fn($row) => !array_diff_assoc($filters, $row)
    )
);

For best performance, use a conditionally breakable loop which will check each key-value pair in the filters array against each row. This assumes/requires that all keys nominated in filters will be guaranteed to exist in the $users array. (Demo)

var_export(
    array_filter(
        $users,
        function($row) use($filters) {
            foreach ($filters as $fkey => $fval) {
                if ($row[$fkey] != $fval) {
                    return false;
                }
            }
            return true;
        }
    )
);

Upvotes: 1

timhpb
timhpb

Reputation: 320

To filter, you need to iterate over all the filters in the filterFunc callback function and check if the filter applies. If one does not apply return false immediatly, else return true:

<?php

$users = array(
    0 => array(
    "name" => "ali",
    "age" => 22,
    "score" => 12
    ),
    1 => array(
    "name" => "hasan",
    "age" => 32,
    "score" => 52
    ),
);

$filters = array(
    "name" => "ali",
    "age" => 22
);

function filterFunc($item) {
    global $filters;
    foreach ($filters as $key => $value) {
        if ($item[$key] != $value) {
            return false;
        }
    }
    return true;
}
$filtered_users = array_filter($users, "filterFunc");   
print_r($filtered_users);

?>

Upvotes: 1

Related Questions