У меня многомерный массив, который выглядит так:
Array ( [0] => Array ( [0] => Array ( [id] => 3 ) [1] => Array ( [id] => 1 ) [2] => Array ( [id] => 2 ) [3] => Array ( [id] => 5 ) [4] => Array ( [id] => 4 ) ) [1] => Array ( [0] => Array ( [id] => 1 ) [1] => Array ( [id] => 3 ) [2] => Array ( [id] => 4 ) [3] => Array ( [id] => 5 ) ) [2] => Array ( [0] => Array ( [id] => 3 ) ) )
Мне нужно найти способ возврата пересекающихся значений. В этом случае это будет
[id] => 3
Длина массива может быть разной, поэтому я не могу просто использовать array_intersect ().
Это было бы просто, если бы ваши массивы содержали только целые числа, но поскольку они содержат другой массив, это становится немного сложнее. Но это должно сделать это:
function custom_intersect($arrays) { $comp = array_shift($arrays); $values = array(); // The other arrays are compared to the first array: // Get all the values from the first array for comparison foreach($comp as $k => $v) { // Set amount of matches for value to 1. $values[$v['id']] = 1; } // Loop through the other arrays foreach($arrays as $array) { // Loop through every value in array foreach($array as $k => $v) { // If the current ID exists in the compare array if(isset($values[$v['id']])) { // Increase the amount of matches $values[$v['id']]++; } } } $result = array(); // The amount of matches for certain value must be // equal to the number of arrays passed, that's how // we know the value is present in all arrays. $n = count($arrays) + 1; foreach($values as $k => $v) { if($v == $n) { // The value was found in all arrays, // thus it's in the intersection $result[] = $v; } } return $result; }
$arrays = array( array(array('id' => 3), array('id' => 1), array('id' => 2), array('id' => 5), array('id' => 4)), array(array('id' => 1), array('id' => 3), array('id' => 4), array('id' => 5)), array(array('id' => 3)) ); print_r(custom_intersect($arrays));
Array ( [0] => 3 )
Эта функция не идеальна: если у вас есть дубликаты идентификаторов в одном массиве, это не сработает. Для этого потребуется немного больше кода, чтобы сделать значения массива уникальными, но это, вероятно, будет работать в вашем случае.
Вы можете использовать array_uintersect()
чтобы получить пересечение массивов с помощью специальной функции сравнения. Вы должны называть его с помощью call_user_func_array()
хотя он ожидает, что каждый массив будет отдельным аргументом:
//build list of parameters for array_uintersect() $params = array_merge($input, array('compare_func')); $result = call_user_func_array('array_uintersect', $params); function compare_func($a, $b) { return $a['id'] - $b['id']; }
Вы не можете просто вызвать array_intersect()
с помощью call_user_func_array()
, потому что, похоже, сравнивают массивы, сравнивая их строковое представление (которое всегда будет «Array»).
$a = array(4,3); $b = array(4,3,2,1); $c = array(1,2,3,4,5); $d = array(5,4,3); $array = array($a,$b,$c,$d); for ($i=0; $i<count($array); $i++){ if ($i==0){ $array2 = $array[$i]; } else { $array2 = array_intersect($array2, $array[$i]); } } print_r($array2);`
Результат:
3,4
Как упоминалось в одном из комментариев веб-сайта php.net (функция array_intersect).
$a = array(1,2,3,4,5,2,6,1); /* repeated elements --> $a is not a set */ $b = array(0,2,4,6,8,5,7,9,2,1); /* repeated elements --> $b is not a set */ $ua = array_merge(array_unique($a)); /* now, $a is a set */ $ub = array_merge(array_unique($b)); /* now, $b is a set */ $intersect = array_merge(array_intersect($ua,$ub));
Это вернет этот массив:
Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 5 [4] => 6 )