仅在关联二维数组中保留在另一个关联二维数组中找不到的第二级值

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

我创建了一个函数来方便将

array_diff()
与两个二维数组一起使用,但这还不够。

<?php
$arraySession = array(
    'sampleA' => array('1', '2', '3'),
    'sampleB' => array('1', '2', '3'),
);

$arrayPost = array(
    'sampleA' => array('1'),
    'sampleB' => array('1', '2'),
);

结果应该是:

array(
   'sampleA' => array('2', '3')
   'sampleB' => array('3'),
)

我现有的功能:

public function array_diff_multidimensional($session, $post) { 
    $result = array();
    foreach ($session as $sKey => $sValue) {
        foreach ($post as $pKey => $pValue) {
            if ((string) $sKey == (string) $pKey) {
                $result[$sKey] = array_diff($sValue, $pValue);
            } else {
                $result[$sKey] = $sValue;
            }
        }
    }
    return $result;
}
php arrays multidimensional-array filter array-difference
4个回答
3
投票

不是我的功能,也没有经过我的测试,但这是 php.net/array_diff 上的第一批评论之一(归功于 gmail dot com 的 thefrox)

<?php
function multidimensional_array_diff($a1, $a2) {
    $r = array();

    foreach ($a2 as $key => $second) {
        foreach ($a1 as $key => $first) {
          if (isset($a2[$key])) {
              foreach ($first as $first_value) {
                  foreach ($second as $second_value) {
                      if ($first_value == $second_value) {
                          $true = true;
                          break;
                      }
                  }
                  if (!isset($true)) {
                      $r[$key][] = $first_value;
                  }
                  unset($true);
              }
          } else {
              $r[$key] = $first;
          }
        }
    }
    return $r;
}
?>

1
投票

这应该可以做到,假设所有键都出现在两个数组中:

$diff = array();
foreach ($session as $key => $values) {
    $diff[$key] = array_diff($values, $post[$key]);
}

或者,因为我很无聊并且

array_map
没有得到充分利用:

$diff = array_combine(
    array_keys($session),
    array_map(function ($a, $b) { return array_diff($a, $b); }, $session, $post)
);

(假设数组有序。)


1
投票

你想要或多或少像这样的东西:

public function array_diff_multidimensional($arr1, $arr2) {
    $answer = array();
    foreach($arr1 as $k1 => $v1) {
        // is the key present in the second array?
        if (!array_key_exists($k1, $arr2)) {
           $answer[$k1] = $v1; 
           continue;
        }

        // PHP makes all arrays into string "Array", so if both items
        // are arrays, recursively test them before the string check
        if (is_array($v1) && is_array($arr2[$k1])) {
            $answer[$k1] = array_diff_multidimensional($v1, $arr2[$k1]);
            continue;
        }

        // do the array_diff string check
        if ((string)$arr1[$k1] === (string)$arr2[$k1]) {
            continue;
        }

        // since both values are not arrays, and they don't match,
        // simply add the $arr1 value to match the behavior of array_diff
        // in the PHP core
        $answer[$k1] = $v1;
    }

    // done!
    return $answer;
}

0
投票

array_reduce()
可用于执行基于行的过滤并保留第一级关联键。在下面的脚本中,使用数组联合运算符 (
+
) 将新的关联元素推入结果数组中。 演示

$arraySession = [
    'sampleA' => ['1', '2', '3'],
    'sampleB' => ['1', '2', '3'],
];

$arrayPost = [
    'sampleA' => ['1'],
    'sampleB' => ['1', '2'],
];

var_export(
    array_reduce(
        array_keys($arraySession),
        fn($result, $k) => $result
            + [$k => array_diff($arraySession[$k], $arrayPost[$k] ?? [])],
        []
    )
);

输出:

array (
  'sampleA' => 
  array (
    1 => '2',
    2 => '3',
  ),
  'sampleB' => 
  array (
    2 => '3',
  ),
)

@deceze 已经演示了使用

foreach
循环的等效效果。 如果 post 数组可能不包含会话数组中存在的所有键,则回退到空数组或完全跳过
array_diff()
调用。 演示

$result = [];
foreach ($arraySession as $k => $row) {
    $result[$k] = array_diff($row, $arrayPost[$k] ?? []);
}
var_export($result);

在 foreach 循环中通过引用修改行将无法正常工作。 演示

$result = [];
foreach ($arraySession as $k => &$row) {
    $row = array_diff($row, $arrayPost[$k] ?? []);
}
var_export($result);
© www.soinside.com 2019 - 2024. All rights reserved.