Как объединить 2 ассоциативных массива в php так, чтобы мы не перезаписывали дублирующиеся записи во всех случаях? - PullRequest
11 голосов
/ 27 января 2010

У меня есть два ассоциативных массива, которые имеют много одинакового содержимого, и поэтому я хочу объединить эти два массива таким образом, чтобы при наличии a в массиве 1 и a в массиве 2, чем в массиве 3, я должен был иметь записи для a's, а не 1.

Я пытался использовать array_merge, но он перезаписывал бы записи в 1-м массиве, если во 2-м массиве есть дубликаты, я также пытался использовать +, но он дает мне фатальную ошибку, говоря Fatal error: Unsupported operand types in /home/code.php, тогда я пытался сделать

(array)$ar3 = (array)$ar1 +(array)$ar2 и, кажется, складывается. Я хочу знать, является ли это правильным способом сделать это, а также, почему изначально я получил фатальную ошибку и чем это сработало, поскольку я уже определил $ ar3, $ ar2, $ ar1 как типы массивов.

$orders = new Order(); 
$prospectOffers = $orders->getOrder($orderConfNumber); 
$prospectOffersResult = json_decode($prospectOffers,true); 
$shoppingBasket = $cart->getCartItems(); 
var_dump($prospectOffersResult); // Both are arrays 
var_dump($shoppingBasket); //Both are arrays 
(array)$result = (array)$prospectOffersResult+(array)$shoppingBasket;

Спасибо.

Ответы [ 2 ]

14 голосов
/ 28 января 2010

$array1 + $array2 вернет объединение двух массивов.Если они являются ассоциативными, значения из левого операнда будут предпочтительными, если ключи сталкиваются.Следовательно, это не то решение, которое вам нужно, поскольку значения будут потеряны.

Нет ничего плохого в утверждении, если обе переменные понимаются как массивы.Вероятно, ваша фатальная ошибка произошла из-за того, что одна переменная на самом деле была объектом, и можно ошибиться, используя var_dump.Добавив приведение типов, вы заставили PHP принудительно преобразовать обе переменные в массивы.Если бы одна переменная была объектом, она имела бы такой эффект:

Из PHP.net Manual

"Если объект преобразован в массив,В результате получается массив, элементы которого являются свойствами объекта. Ключи - это имена переменных-членов, за некоторыми заметными исключениями: целочисленные свойства недоступны, частные переменные имеют имя класса, добавленное к имени переменной, защищенные переменные имеют '*'перед именем переменной. Эти предопределенные значения имеют нулевые байты с обеих сторон. "

Теперь, имея два массива для добавления, PHP не о чем паниковать.Обратите внимание, что хотя приведение двух операндов + было важно, бессмысленно приводить переменную, которую вы присваивали.Выражение (array)$foo не изменяет $ foo, а скорее возвращает новое значение.Это может быть не интуитивно понятно в языках, требующих объявления переменных, но PHP не является таким языком.

Что касается другой проблемы, у вас не может быть двух одинаковых ключей в массиве.Это сделало бы невозможным индексирование массива, поскольку правильное возвращаемое значение стало бы неоднозначным.Если вы хотите объединить два массива в усадьбе без потерь, вам придется использовать более сложную структуру данных.

Я предлагаю использовать массив массивов, где:

$a1 = array('a' => 1, 'b' => 2, 'c' => 3);
$a2 = array('a' => 3, 'b' => 2, 'd' => 2);

Станет:

$a3 = array(
    'a' => array(1, 3),
    'b' => array(2, 2),
    'c' => array(3),
    'd' => array(2)
);

И порядок не определяется.Единственное заметное изменение в структуре состоит в том, что все первые значения являются массивами, что позволяет накапливать значения дубликатов ключей.Эта функция выполняет задачу и может сделать с лучшим именем:

// array(array) lossless_array_merge([$array1 [, $array2 [, $...]]])

function lossless_array_merge() {
  $arrays = func_get_args();
  $data = array();
  foreach ($arrays as $a) {
    foreach ($a as $k => $v) {
      $data[$k][] = $v;
    }
  }
  return $data;
}
1 голос
/ 27 января 2010

array_merge() заменит дубликаты, только если оба массива содержат одинаковые строковые ключи :

Если входные массивы имеют одинаковые строковые ключи, затем более позднее значение для этот ключ перезапишет предыдущий один. Если, однако, массивы содержат цифровые клавиши, позднее значение не будет перезаписать исходное значение, но быть добавленным.

Я считаю, что такое поведение ожидается. Как вы справитесь с этим делом? Допустим, что

$arr1 = array('a' => 1);
$arr2 = array('a' => 2);

Что будет приемлемым выводом после слияния массива?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...