简体   繁体   中英

Filter array rows by matching one or more key-value pairs in associative array

Suppose,

$data = array(
   array('id' => 1, 'user_id' => 1, 'assignment_id' => 1, 'grade' => 90),
   array('id' => 2, 'user_id' => 3, 'assignment_id' => 2, 'grade' => 85),
   array('id' => 3, 'user_id' => 5, 'assignment_id' => 5, 'grade' => 66),
);

Now I want to filter the rows like following:

$rules = array(
    'user_id' => 5,
    'assignment_id' => 5
);

This should return the row at $data[2] .

$rules = array(
    'user_id' => 3,
    'assignment_id' => 2,
    'grade' => 85
);

will return $data[1] .

Here order of keys may be different both in $data elements and $rules .

I tried with array_intersect , but that is not working for me.

If you just need to return a list of of the elements in $data which match the filtering criteria, you can use a combination of array_filter() and array_intersect_assoc() to do the job:

// build an array of your filtering criteria
$filter_array = array(
   'user_id' => 3,
   'assignment_id' => 5
);

// filter the array
$filtered_array = array_filter($data, function ($val_array) use ($filter_array) {
    $intersection = array_intersect_assoc($val_array, $filter_array);
    return (count($intersection)) === count($filter_array);
});

Note that you need PHP >= 5.3.0 to utilize the anonymous function as shown.

Here is a more modern and elegant approach.

Use arrow function syntax to allow $rules into the custom function's scope. Associatively filter the rules array by each encountered row, then return a true evaluation if the rules array is identical to the rules array that was associatively filtered.

Code: ( Demo )

$data = [
   ['id' => 1, 'user_id' => 1, 'assignment_id' => 1, 'grade' => 90],
   ['id' => 2, 'user_id' => 3, 'assignment_id' => 2, 'grade' => 85],
   ['id' => 3, 'user_id' => 5, 'assignment_id' => 5, 'grade' => 66],
];

$rules = ['user_id' => 3, 'assignment_id' => 2];

var_export(
    array_filter(
        $data,
        fn($row) => $rules === array_intersect_assoc($rules, $row)
    )
);

Output:

array (
  1 => 
  array (
    'id' => 2,
    'user_id' => 3,
    'assignment_id' => 2,
    'grade' => 85,
  ),
)

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