比较两个关联二维数组之间的差异,并在用默认值填充一个数组后,丢弃没有差异的行

问题描述 投票:0回答:7

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

  • 打印从 MySQL 提取的用户和权限表。用户拥有的每一项权限都是一个复选框,而他们缺少的每一项权限都是一个未选中的复选框。
  • 允许管理员选中和取消选中复选框以授予或删除权限。
  • 提交表单后,显示一个确认页面,其中仅包含将更改权限的用户,突出显示特定更改。
  • 确认更改后,相应修改数据库。

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

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

这是数组的两个简单示例:

数据库数组

[User1] => 数组([public] => 1
                [私人] => 1
                [秘密] => 1
               )
[User2] => 数组 ([public] => 1
                [私人] => 0
                [秘密] => 0
               )

表单提交数组(撤销User1的“秘密”并将其交给User2)

[User1] => 数组([public] => 1
                [私人] => 1
               )

[User2] => 数组 ([public] => 1
                  [秘密] => 1
                 )

问题

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

  • 两者具有相同权限的用户被省略
  • 其余用户拥有所有权限 - 公共、私有和秘密 - 设置为 0 或 1。
  • 如果表单提交数组中缺少每个权限,则为 0;如果表单提交数组中存在,则为 1

例如,结合以上内容将得到:

[User1] => 数组([public] => 1
                [私人] => 1
                [秘密] => 0
               )
[User2] => 数组 ([public] => 1
                [私人] => 0
                [秘密] => 1
               )

迄今为止的尝试

  • 作为第一步,我尝试使用 array_merge() 与第二个列出的表单数组,认为它会覆盖它们不同的数据库数组。相反,它删除了不同的元素。
  • 我尝试过设置一个 foreach() 语句来比较两个数组,但是它变得很复杂,我认为必须有一个更简单的方法

更新

哇!一个新的答案让我的注意力又回到了这个老问题上。我得到了这个工作,但后来我废弃了这个疯狂的代码 - 它太复杂了,无法返回并使用。相反,我编写了一个 PHP 后端脚本来一次更改一个权限,然后编写了一个 AJAX 前端来发送更改。代码更加简单,并且更改对于用户来说是即时的。突出显示效果可提供有关更改内容的即时页面反馈。

php arrays multidimensional-array default-value array-difference
7个回答
2
投票

这可能就是您正在寻找的: array_diff()


2
投票

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

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


2
投票

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

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


1
投票

让我们尝试将 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
投票

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


0
投票

要使用

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
投票

将零填充行与数据库行进行比较:

  1. 填充一个平面关联数组,其中包含所有可能的列名称为零值。您可以对这些值进行硬编码或从第一个数据库行访问它们。
  2. 迭代表单提交数据
  3. 假设所有表单提交都在数据库中找到,在用默认零填充提交行后,如果用户的新数据不包含相同的关联数据(以任何顺序),则将该行推入结果中。

代码:(演示

$result = [];
foreach ($form as $user => $row) {
    /*if (!isset($database[$user])) {
        continue;
    }*/
    $new = array_replace($defaults, $row);
    if ($db[$user] != $new) {
        $result[$user] = $new;
    }
}
var_export($result);
© www.soinside.com 2019 - 2024. All rights reserved.