Как я могу сравнить два массива и список различий в PHP? - PullRequest
3 голосов
/ 02 февраля 2009

Я создаю форму для следующих действий:

  • Распечатка таблицы пользователей и разрешений, извлекаемых из MySQL. Каждое разрешение, которое есть у пользователя, является отмеченным флажком, а каждое из них, которое им не хватает, является отмеченным флажком.
  • Разрешить администратору устанавливать и снимать флажки для предоставления или удаления разрешений.
  • Когда форма отправлена, покажите страницу подтверждения ТОЛЬКО пользователями, чьи разрешения будут изменены, выделив конкретные изменения.
  • Когда изменения будут подтверждены, измените базу данных соответствующим образом.

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

Если у пользователя нет разрешения в MySQL, оно будет отображаться как 0. Если у него нет разрешения при отправке формы, его просто не будет.

Вот два простых примера массивов:

Массив базы данных

[User1] => Array ([public] => 1
                [private] => 1
                [secret] => 1
               ) 
[User2] => Array ([public] => 1
                [private] => 0
                [secret] => 0
               )

Массив отправки формы (отзыв «секретного» из User1 и передача его User2)

[User1] => Array ([public] => 1
                [private] => 1 
               )

[User2] => Array ([public] => 1
                  [secret] => 1
                 )

Вопрос

Как мне элегантно объединить эти два массива , чтобы создать массив "изменений", такой что:

  • Пользователи с одинаковыми разрешениями в обоих случаях не указываются
  • Остальные пользователи имеют все разрешения - общедоступные, частные и секретные - равные 0 или 1.
  • Каждое разрешение равно 0, если оно отсутствовало в массиве отправки формы, и 1, если оно было в массиве отправки формы

Например, объединение вышеперечисленного даст:

[User1] => Array ([public] => 1
                [private] => 1
                [secret] => 0
               ) 
[User2] => Array ([public] => 1
                [private] => 0
                [secret] => 1
               )

Попытки пока

  • В качестве первого шага я попытался использовать array_merge () с указанным на втором месте массивом форм, полагая, что он перезапишет массив базы данных там, где они различаются. Вместо этого были удалены элементы, которые отличались.
  • Я попытался настроить оператор foreach () для сравнения двух массивов, но это становится сложным, и я думаю, что должен быть более простой способ
* * ОБНОВЛЕНИЕ тысячи сорок-девять

Уф! Новый ответ снова привлек мое внимание к этому старому вопросу. У меня все получилось, но позже я удалил этот сумасшедший код - он был слишком сложным, чтобы вернуться и работать с ним. Вместо этого я написал PHP-сценарий для изменения одного разрешения за раз, затем написал AJAX-интерфейс для отправки изменений по нему. Гораздо более простой код, и изменения происходят мгновенно для пользователя. Эффект выделения позволяет мгновенно получить на странице информацию о том, что изменилось.

Ответы [ 6 ]

2 голосов
/ 02 февраля 2009

Данные публикации содержат только те разрешения, которые вы должны предоставить. Итак, установите «базовый уровень» со всеми разрешениями, установленными на 0. Затем объедините с представлением.

$empty_perms = array("public" => 0, "private" => 0, "secret" => 0);

$new_user1_perms = array_merge($empty_perms, $_POST['User1']);
$new_user2_perms = array_merge($empty_perms, $_POST['User2']);

Теперь обновите базу данных, используя объединенные массивы. Таким образом, вы установите правильные разрешения для всех элементов.

2 голосов
/ 02 февраля 2009

Вы можете найти то, что вам нужно, обратившись к PHP: Руководство по массивам . Вы достаточно хорошо задокументировали вопрос, но я до сих пор не могу понять, что вам нужно.

В частности, вы должны рассмотреть использование array_diff () и array_intersect () для вычисления разности или пересечения двух массивов.

2 голосов
/ 02 февраля 2009

Это может быть то, что вы ищете: array_diff ()

1 голос
/ 03 февраля 2009

Давайте попробуем объединить решение gnud со сравнением по значению. Я добавил еще один ключевой «член», чтобы показать, что нулевое разрешение не изменилось.

// empty permissions
$empty_perms = array("public" => 0, "private" => 0, "secret" => 0, "member" => 0);

// original permissions (please note that it MUST contain ALL keys)
$old_perms = array("public" => 1, "private" => 0, "secret" => 1, "member" => 0);

// POST data container
$post_data = array("public" => 1, "private" => 1);

// apply new user permissions - put them into db
$new_perms = array_merge($empty_perms, $post_data);

// differences to show
$diff_perms = array();

// compare new and old permissions
foreach($empty_perms as $k => $v) {
    $diff_perms[$k] = (int)($old_perms[$k] !== $new_perms[$k]);
}

Этот пример должен дать вам следующие результаты (старые, новые, изменения):

Array
(
    [public] => 1
    [private] => 0
    [secret] => 1
    [member] => 0
)

Array
(
    [public] => 1
    [private] => 1
    [secret] => 0
    [member] => 0
)

Array
(
    [public] => 0
    [private] => 1
    [secret] => 1
    [member] => 0
)

Надеюсь, это поможет.

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

Чтобы использовать array_diff(), первым аргументом должен быть надмножество или больший из двух массивов. Чтобы использовать array_diff(), когда вы не уверены, какой массив больше, просто:

  //start with the superset of for array_diff to return differences
  if(count($prev_wholesaler_assignments) > count($wholesalers)){
      $perm_diff = array_diff($prev_wholesaler_assignments,$wholesalers);  
  } elseif (count($prev_wholesaler_assignments) < count($wholesalers)){
      $perm_diff = array_diff($wholesalers,$prev_wholesaler_assignments);
  }

Возвращает дизъюнкцию независимо от того, какой массив больше.

0 голосов
/ 02 февраля 2009

Интересно, поможет ли какое-то изменение дифференциального исполнения .

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