如何在PHP中比较两个数组和列表差异?

时间:2022-06-23 12:02:40

I'm building a form to do the following:

我正在构建一个表单来执行以下操作:

  • Print a table of users and permissions, pulling from MySQL. Each permission a user has is a checked box, and each one they lack is an unchecked box.
  • 从MySQL中打印一个用户和权限表。用户拥有的每个权限都是一个复选框,他们缺少的每个权限都是一个未选中的框。

  • Allow an administrator to check and uncheck boxes to grant or remove permissions.
  • 允许管理员选中和取消选中框以授予或删除权限。

  • When the form is submitted, show a confirmation page with ONLY the users whose permissions will be changed, highlighting the specific changes.
  • 提交表单后,只显示一个确认页面,其中只包含权限将被更改的用户,突出显示特定的更改。

  • When the changes are confirmed, modify the database accordingly.
  • 确认更改后,相应地修改数据库。

To do this, I'm creating two arrays of user permissions: one according to what the database shows, and one according to what the form shows.

为此,我创建了两个用户权限数组:一个根据数据库显示的内容,另一个根据表单显示的内容。

If a user lacks a permission in MySQL, it will be shown as a 0. If they lack a permission in the form submission, it simply won't exist.

如果用户在MySQL中缺少权限,它将显示为0.如果他们在表单提交中缺少权限,则它将不存在。

Here are two simple examples of the arrays:

以下是两个简单的数组示例:

Database array

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

Form submission array (revoking "secret" from User1 and giving it to User2)

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

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

Question

How can I elegantly combine these two arrays to make a "changes" array, such that:

我怎样才能优雅地组合这两个数组来创建一个“更改”数组,这样:

  • Users with identical permissions in both are omitted
  • 省略了在两者中具有相同权限的用户

  • Remaining users have all permissions - public, private and secret - set to either 0 or 1.
  • 剩余用户将所有权限(public,private和secret)设置为0或1。

  • Each permission is 0 if it was missing from the form submission array, and 1 if it was in the form submission array
  • 如果表单提交数组中缺少每个权限,则为0;如果表单提交数组中,则为1

For example, combining the above would give:

例如,结合上述内容将给出:

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

Attempts so far

  • As a first step, I have tried using array_merge() with the forms array listed second, thinking it would overwrite the database array where they differed. Instead, it deleted elements that differed.
  • 作为第一步,我尝试使用array_merge(),其中第二个列出了表单数组,认为它会覆盖它们不同的数据库数组。相反,它删除了不同的元素。

  • I have tried setting up a foreach() statement to compare the two arrays, but it's becoming complicated, and I think there must be a simpler way
  • 我已经尝试设置foreach()语句来比较两个数组,但它变得复杂了,我认为必须有一个更简单的方法

UPDATE

Whew! A new answer drew my attention back to this old question. I got this working, but later I scrapped this crazy code - it was way too complicated to go back and work with. Instead, I wrote a PHP back end script to change one permission at a time, then wrote an AJAX front end to send changes over it. Much simpler code, and the changes are instantaneous for the user. A highlight effect gives instant, on-page feedback about what has changed.

呼!一个新的答案引起了我的注意力回到这个老问题。我得到了这个工作,但后来我废弃了这个疯狂的代码 - 回到过去工作太复杂了。相反,我编写了一个PHP后端脚本来一次更改一个权限,然后写了一个AJAX前端来发送更改。更简单的代码,以及对用户的即时更改。突出显示效果可即时提供有关已更改内容的页面反馈。

6 个解决方案

#1


This might be what you are looking for: array_diff()

这可能就是你要找的东西:array_diff()

#2


You can find what you need by referring to the PHP: Arrays manual. You've documented the question quite well but I still can't make it out clearly what is it that you need.

您可以通过参考PHP:Arrays手册找到所需内容。你已经很好地记录了这个问题,但我仍然无法清楚地说明你需要什么。

Specifically you should be looking at using the array_diff() and array_intersect(), to compute the difference or intersection of two arrays.

具体来说,您应该考虑使用array_diff()和array_intersect()来计算两个数组的差异或交集。

#3


The post data only contains the permissions you should grant. So, set up a "baseline" with all the permissions set to 0. Then merge with the submission.

帖子数据仅包含您应授予的权限。因此,设置一个“基线”,将所有权限设置为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']);

Now update the database using the merged arrays. This way you will set correct permissions for all elements.

现在使用合并的数组更新数据库。这样,您将为所有元素设置正确的权限。

#4


Let's try to combine gnud's solution with comparing by value. I've added one more key "member" to show zero permission being unchanged.

让我们尝试将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]);
}

This example should give you following results (old, new, changes):

此示例应该为您提供以下结果(旧的,新的,更改):

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
)

Hope this helps.

希望这可以帮助。

#5


I wonder if some sort of variation on differential execution would help.

我想知道差异执行的某种变化是否会有所帮助。

#6


To use array_diff() the first argument must be the superset, or the larger of the two arrays. To use array_diff() when you are not sure which array is larger simply:

要使用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);
  }

This returns the disjunction regardless of which array happens to be larger.

无论哪个数组碰巧变大,都会返回析取。

#1


This might be what you are looking for: array_diff()

这可能就是你要找的东西:array_diff()

#2


You can find what you need by referring to the PHP: Arrays manual. You've documented the question quite well but I still can't make it out clearly what is it that you need.

您可以通过参考PHP:Arrays手册找到所需内容。你已经很好地记录了这个问题,但我仍然无法清楚地说明你需要什么。

Specifically you should be looking at using the array_diff() and array_intersect(), to compute the difference or intersection of two arrays.

具体来说,您应该考虑使用array_diff()和array_intersect()来计算两个数组的差异或交集。

#3


The post data only contains the permissions you should grant. So, set up a "baseline" with all the permissions set to 0. Then merge with the submission.

帖子数据仅包含您应授予的权限。因此,设置一个“基线”,将所有权限设置为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']);

Now update the database using the merged arrays. This way you will set correct permissions for all elements.

现在使用合并的数组更新数据库。这样,您将为所有元素设置正确的权限。

#4


Let's try to combine gnud's solution with comparing by value. I've added one more key "member" to show zero permission being unchanged.

让我们尝试将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]);
}

This example should give you following results (old, new, changes):

此示例应该为您提供以下结果(旧的,新的,更改):

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
)

Hope this helps.

希望这可以帮助。

#5


I wonder if some sort of variation on differential execution would help.

我想知道差异执行的某种变化是否会有所帮助。

#6


To use array_diff() the first argument must be the superset, or the larger of the two arrays. To use array_diff() when you are not sure which array is larger simply:

要使用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);
  }

This returns the disjunction regardless of which array happens to be larger.

无论哪个数组碰巧变大,都会返回析取。