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

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

Рассмотрим этот пример:

CREATE TABLE parent (
  parent_id INT NOT NULL,
  parent_data int,

  PRIMARY KEY (parent_id)
) ENGINE=INNODB;

CREATE TABLE child1 (
  child1_id INT,
  child1_data INT,
  fk_parent_id INT,

  INDEX par_ind1 (fk_parent_id),

  FOREIGN KEY (fk_parent_id)
    REFERENCES parent(parent_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE=INNODB;

CREATE TABLE child2 (
  child2_id INT,
  child2_data INT,
  fk_parent_id INT,

  INDEX par_ind2 (fk_parent_id),

  FOREIGN KEY (fk_parent_id)
    REFERENCES parent(parent_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE=INNODB;

INSERT INTO parent
  (parent_id, parent_data)
  VALUES
  (1, 11),
  (2, 12);

INSERT INTO child1
  (child1_id, child1_data, fk_parent_id)
  VALUES
  (101, 1001, 1),
  (102, 1002, 1),
  (103, 1003, 1),
  (104, 1004, 2),
  (105, 1005, 2);

INSERT INTO child2
  (child2_id, child2_data, fk_parent_id)
  VALUES
  (106, 1006, 1),
  (107, 1007, 1),
  (108, 1008, 1),
  (109, 1009, 2),
  (110, 1010, 2);

Тогда это разрешено:

UPDATE parent
  SET parent_id = 3 WHERE parent_id = 2;

SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;

Но это не так, потому что он изменяет родительский fk из дочерней таблицы:

UPDATE child1
  SET fk_parent_id = 4 WHERE fk_parent_id = 1;

Он получает ошибку, очень похожую на вашу ошибку:

Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE):
11
задан Gordon 27 January 2010 в 17:31
поделиться

2 ответа

Вы можете использовать код кода Java Script. Что касается форматирования, писатель XML (как я знаю) может выводить хорошо структурированный документ, его можно отключить по умолчанию для уменьшения веса.

-121--4112771-

Array_Merge () будет переопределять дубликаты только в том случае, если оба массива содержат одни и те же строковые клавиши :

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

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

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

, каково было бы приемлемым выходом после слияния массива?

1
ответ дан 3 December 2019 в 08:04
поделиться

Это действительно будет зависеть от того, что вы получаете к немуществу. Рассмотрим следующие два сценария:

Сценарий 1: вы пишете метод для обеспечения общего действия по данным в классе:

// assume a hypothetical class Position

public class Circle
{
    private int _radius;
    private int _xpos;
    private int _ypos;

    public int Radius { get { return _radius; } }
    public Position Center { get { return new Position(_xpos, _ypos); } }

    public bool PointInCircle(Position other)
    {
         return distance(this.Center, other) < this.Radius;
    }
}

Очевидно, что поведение точечного точка должно быть таким же, как если пользователь выполнил код внутри него. Поэтому имеет смысл использовать публичные свойства.

Сценарий 2: Вы пишете метод для манипулирования основными данными. Хорошим примером этого является сериализация. Вы хотели бы сериализовать основные элементы данных, в отличие от значений, возвращаемых доступами имущества.

-121--2975491-

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

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

из Руководства

», если объект преобразуется в массив, Результатом является массив, элементы которых являются свойствами объекта. Ключи имена переменных участников с Несколько заметных исключений: целое число свойства недоступны; частный Переменные имеют имя класса добавлено к имени переменной; Охраняемые переменные имеют «*» добавлено к имени переменной. Эти предложенные значения имеют нулевые байты на Любая сторона.

Теперь, имея два массива, чтобы добавить, PHP не имел ничего паниковать. Обратите внимание, что при отливании двух операндов + было важно, было бессмысленным, чтобы изменить переменную, вы присваиваете , Выражение (массив) $ 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)
);

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

// 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;
}
14
ответ дан 3 December 2019 в 08:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: