3

I'm trying to make advanced search filters in an application that holds resources (people). I've got all the results in 1 multidimensional array. A user of the application can search for the persons Job title, skills, work field and country.

I've already made the part where I look up the people that meet the criteria given by the user. These results are stored in a multidimensional array. If the user is looking for someone with a specific resource with a job title and a specific skill the return value is this:

$realfilters = array(2) {
["resourcesWithJobtitle"]=> array(6) {
   [0]=> string(1) "1"
   [1]=> string(2) "48"
   [2]=> string(2) "88"
}
["resourcesWithSkill"]=> array(9) {
   [0]=> string(1) "4"
   [1]=> string(1) "8"
   [2]=> string(1) "48"
   [3]=> string(2) "50"
}

When the user also looks for a work field this is added to the result:

["resourcesWithWorkfield"]=> array(3) {
   [0]=> string(2) "48"
   [1]=> string(2) "96"
   [2]=> string(2) "97"
}

I need to know which resources meet all dimensions of the array so I can display them. (So in this example I need an array with just 1 value: 48). I think I need to use array_intersect but can't seem to get it right.

rodrigo-silveira
  • 12,607
  • 11
  • 69
  • 123
Mettin Parzinski
  • 838
  • 1
  • 7
  • 13

2 Answers2

4

One of the possible solutions: you may first extract() the $realfilters array values to variables, and then apply the array_intersect() to them. But this solution is applicable only if there are not many possible filters.

Another one and probably the best solution would be to intersect in a loop, something like:

$res_arr = array_shift($realfilters);
foreach($realfilters as $filter){
     $res_arr = array_intersect($res_arr, $filter);
}
user2428118
  • 7,935
  • 4
  • 45
  • 72
  • Seems like the way to go but isn't working: [code]if(!empty($realfilters)) { $resourceIDsThatMatchAllCritera = $realfilters[0]; for ($i = 1; $i < count($realfilters); $i++) { $resourceIDsThatMatchAllCritera = array_intersect_key($resourceIDsThatMatchAllCritera, $realfilters[$i]); } var_dump($resourceIDsThatMatchAllCritera); // empty }[/code] – Mettin Parzinski Jun 08 '12 at 14:53
  • 1
    Got it. $realfilters[0] doesn't work. Changed it to $realfilters["resourcesWithJobtitle"] and now it works! – Mettin Parzinski Jun 08 '12 at 15:32
  • Yeah. Just noticed that also :) But better solution just came to my mind (in case you don't know the key): $resourceIDsThatMatchAllCritera = array_shift($realfilters); foreach($realfilters as $filter){ $resourceIDsThatMatchAllCritera = array_intersect($resourceIDsThatMatchAllCritera, $filter); } – Alexander Gilmanov Jun 08 '12 at 15:35
  • @MettinParzinski by the way, why do you use array_intersect_key? keys are just indexes (0,1,2) in your case... – Alexander Gilmanov Jun 08 '12 at 15:40
  • That's a mistake. This is my final code: if(!empty($realfilters)) { $resourceIDsThatMatchAllCritera = $allResourceIDs; foreach ($realfilters as $key => $value) { $resourceIDsThatMatchAllCritera = array_intersect($resourceIDsThatMatchAllCritera, $realfilters[$key]); } } – Mettin Parzinski Jun 09 '12 at 12:21
  • OK, I see. Anyway, I think that the most clean & nice and also universal solution was offered by @chris :) – Alexander Gilmanov Jun 09 '12 at 12:27
4
$intersection = call_user_func_array('array_intersect', $array);

That will give you the elements present in all the sub arrays of $array.

edit- This above is like a shortcut for writing:

$intersection = array_intersect($array['a'], $array['b'], ...and so on for all elements...);

A loop could be used as well

$intersection = reset($array);
foreach ($array as $subarr) {
    $intersection = array_intersect($intersection, $subarr);
}
print_r($intersection);
goat
  • 31,486
  • 7
  • 73
  • 96