Edit #2:
By moving all values to be compared to key positions, php can more than double efficienct (by my demo's system time metric).
Furthermore, if you have duplicate values in your subsets, calling array_flip() will reduce the size by disallowing duplicate keys.
Code: (Demo)
$A = array_flip($A); // prepare for key comparisons
$result = [];
foreach ($B as $key => $haystack) {
if (array_intersect_key(array_flip($haystack), $A)) {
$result[] = $key;
}
}
var_export($result);
Edit:
Whenever you want to optimize array searching with php, it is often best to try to prepare your data in a way which allows php to leverage its strength with hash tables. https://codedmemes.com/lib/best-performance-array-intersection/
Consider this preparation...
Code: (Demo)
foreach ($B as $key => $haystack) {
foreach ($haystack as $hay) {
$C[$hay][] = $key;
}
}
var_export(array_keys(array_flip((array_merge(...array_intersect_key($C, array_flip($A)))))));
Output:
array (
0 => 1,
1 => 2,
2 => 4,
)
- The nested
foreach() loops generate a collection of subarrays which have unique values from B's subarrays as keys and $B's original keys as new subarray values.
array_intersect_key() checks the keys which php does much faster than checking values. (see first hyperlink article)
- Then
array_merge(...) flattens the subarrays into a single 1-dim array.
- Finally
array_flip() and array_keys() removes duplicates and re-indexes the results.
I don't know exactly how array_intersect() works its magic in terms of efficiency, but this is probably how I'd go about it:
Code: (Demo)
$A = [3,45,67,8];
$B = [ 1 => [1,6,8],
2 => [5,67,3,4,5,66,6],
3 => [55,56,57,58],
4 => [45,80,81,82]
];
$result = [];
foreach ($B as $key => $haystack) {
if (array_intersect($haystack, $A)) { // generate an array with co-existing values
$result[] = $key; // add key if array_intersect makes a non-empty array
}
}
var_export($result);
Output:
array (
0 => 1,
1 => 2,
2 => 4,
)
I suppose if there is a "downside" to using array_intersect() it would be that it will bother to make multiple matches, when only a single match per row is necessary. For this reason, array_search() or a breaking loop might have advantages.
Code: (Demo)
$result = [];
foreach ($B as $key => $haystack) {
foreach ($haystack as $hay) {
if (in_array($hay, $A)) {
$result[] = $key;
break;
}
}
}
var_export($result); // same result
1a qualifying key? It contains8which is in the whitelist.B. it can't get better than that.