PHP: Как получить массив различий при сравнении двух ассоциированных массивов и получить только значения, которые встречаются только в одном из них?
Извините за беспокойство. У меня такая проблема, есть два массива:
1)
$array1 = array(
'фрукт' => array('яблоко', 'груша', 'апельсин', 'лимон'),
'овощь' => array('кабачок', 'капуста', 'патисон'),
'ягода' => array('малина', 'земляника'),
);
$array2 = array(
'фрукт' => array('груша', 'слива', 'апельсин'),
'овощ' => array('кабачок', 'капуста', 'картошка'),
);
Нужно сравнить второй с первым и получить новый массив, в котором есть только значения и ключи, которые не встречаются в $array2. В $array1 могут попасться новые ключи, которых вовсе нет в $array2, в идентичном ключе, который присутствует в обоих массивах может найтись новое значение. Оно есть в $array1, но еще не добавилось в $array2. Подскажите, пожалуйста, как сравнить $array1 с $array2 и получить массив с разницей: если ключ в $array2 есть, то только новое значение, которое можно найти в $array1, если ключа в $array2 нет, то добавить в результирующий массив и новый ключ и все его значения.
Что пробовал?
Пробовал $array_diff(), $array_diff_assoc(). Второй должен бы сработать, но вернул пустой массив, хотя разница в двух массивах была. Попробовал написать свою функцию с двумя foreach
foreach ($array1 as $fl) {
foreach ($array2 as $subfl) {
}
}
Тоже ничего не вышло...
Ответы (3 шт):
Надо отсортировать массивы. После этого можно будет решить за линию от суммарного размера методом "двух указателей".
Попробуйте так, если я правильно понял ваш вопрос:
<?php
$array1 = array(
'фрукт' => array('яблоко', 'груша', 'апельсин', 'лимон'),
'овощь' => array('кабачок', 'капуста', 'патисон'),
'ягода' => array('малина', 'земляника'),
);
$array2 = array(
'фрукт' => array('груша', 'слива', 'апельсин'),
'овощь' => array('кабачок', 'капуста', 'картошка'),
);
function array_compare($array1, $array2)
{
$diff = array();
foreach ($array1 as $key => $values)
{
if (!array_key_exists($key, $array2))
$diff[$key] = $values;
else
{
$diff[$key] = array();
foreach ($values as $value)
if (!in_array($value, $array2[$key]))
array_push($diff[$key], $value);
}
}
return $diff;
}
$dif = array_compare($array1, $array2);
print_r($dif);
На выходе получаем элементы которые есть в 1 массиве, но нет во втором
Array
(
[фрукт] => Array
(
[0] => яблоко
[1] => лимон
)
[овощь] => Array
(
[0] => патисон
)
[ягода] => Array
(
[0] => малина
[1] => земляника
)
)
Вариант для двух аргументов(По сути не отличается от варианта Tunker):
<?php
// Your code here!
$array1 = [
'фрукт' => ['яблоко', 'груша', 'апельсин', 'лимон'],
'овощ' => ['кабачок', 'капуста', 'патисон'],
'ягода' => ['малина', 'земляника'],
'зелень' => ['кинза','базилик'],
];
$array2 = [
'фрукт' => ['груша', 'слива', 'апельсин'],
'овощ' => ['кабачок', 'капуста', 'картошка'],
];
function diff(array $array1, array $array2): array {
$result = $array1;
foreach ($result as $key => $values){
if( array_key_exists($key, $array2)){
$result[$key] = array_diff($values, $array2[$key]);
if($result[$key] === []){
unset($result[$key]);
}
}
}
return $result;
}
print_r(diff($array1, $array2));
?>
Вариант для неопределённого количества аргументов.
<?php
$array1 = [
'фрукт' => ['яблоко', 'груша', 'апельсин', 'лимон'],
'овощ' => ['кабачок', 'капуста', 'патисон'],
'ягода' => ['малина', 'земляника'],
'зелень' => ['кинза','базилик'],
];
$array2 = [
'фрукт' => ['груша', 'слива', 'апельсин'],
];
$array3 = [
'овощ' => ['кабачок', 'капуста', 'картошка'],
'зелень' => ['кинза','базилик'],
];
function diff(...$arrays): array {
if($arrays === []){
return [];
}
$len = count($arrays);
$result = $arrays[0];
for($i = 1; $i < $len; $i++){
foreach ($result as $key => $value) {
if(array_key_exists($key, $arrays[$i])){
$result[$key] = array_diff($value, $arrays[$i][$key]);
if($result[$key] === []){
unset($result[$key]);
}
}
}
}
return $result;
}
print_r(diff($array1, $array2, $array3));
?>