I am trying to filter 2d arrays which satisfy two conditions. But, it not works as expected. I figured out that error is in array_intersect()
function. Why array_intersect()
not works correctly here.Is there another way to do this without iteration.
<?php
error_reporting(0);
$students = [
["name"=> 'k. l.james', "grade"=>8],
["name"=> 'k. l.james', "grade"=>9],
["name"=> 'e. musk', "grade"=>8],
["name"=> 'jone', "grade"=>9],
];
function filterByGrade($grade){
global $students ;
if (empty($grade)){
return $students ;
}else{
return array_filter($students , function($record) use($grade){
return ($record['grade'] == $grade);
});
}
}
function filterByName($name){
global $students;
if (empty($name)){
return $students;
}else{
return array_filter($students, function($record) use($name){
return (strcasecmp(str_replace(' ','',$record['name']),str_replace(' ','',$name)) == 0);
});
}
}
print_r(filterByGrade(8));
echo "<br/>";
print_r(filterByName('k.l.james'));
echo '<br/>';
print_r(array_intersect(filterByGrade(8), filterByName('k.l.james')));
?>
results are;
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [2] => Array ( [name] => e. musk [grade] => 8 ) )
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [1] => Array ( [name] => k. l.james [grade] => 9 ) )
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [2] => Array ( [name] => e. musk [grade] => 8 ) )
I expect the last line of result as,
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ))
If I interchanged the two arrays in array_intersect() as follows, the results are different.
print_r(array_intersect(filterByName('k.l.james'),filterByGrade(8)));
Then,I get result as follows.
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [2] => Array ( [name] => e. musk [grade] => 8 ) )
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [1] => Array ( [name] => k. l.james [grade] => 9 ) )
Array ( [0] => Array ( [name] => k. l.james [grade] => 8 ) [1] => Array ( [name] => k. l.james [grade] => 9 ) )
I noticed that only the first filtered array in array_intersect()
is printed despite of considering the intersection of the two arrays.
You can create a function to filter students using multiple conditions, instead of trying to combine the 2 results.
The function :
/**
* Here, $condition array of keys/values used to filter $data.
* ex: ['name' => 'jone', 'grade' => 9]
*/
function filterArray($data, $conditions)
{
if (empty($conditions)) {
return $data;
}
return array_filter($data, function($record) use ($conditions) {
// Check all given conditions
foreach ($conditions as $key => $value) {
// If doesn't match, return false (don't keep in filtered array)
if ($record[$key] != $value) return false;
}
// conditions passed, add to array
return true;
});
}
Usage :
$students = [
["name"=> 'k. l.james', "grade" => 8],
["name"=> 'k. l.james', "grade" => 9],
["name"=> 'e. musk', "grade" => 8],
["name"=> 'jone', "grade" => 9],
];
print_r(filterArray($students, ['grade' => 8]));
// out : [["name"=> 'k. l.james', "grade" => 8],["name"=> 'e. musk', "grade" => 8]]
print_r(filterArray($students, ['name' => 'k. l.james']));
// out : [["name"=> 'k. l.james', "grade" => 8], ["name"=> 'k. l.james', "grade" => 9]]
print_r(filterStudents($students, ['grade' => 8, 'name' => 'k. l.james']));
// out : [["name"=> 'k. l.james', "grade" => 8]]
Additional notes :
global
is discouraged, in the code below, $students
are given by the function parameter.else
statement after a "return early" pattern (if ($someCondition) { return; } else { }
).