简体   繁体   中英

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');

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);

?>

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;
        }
    )
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM