循环遍历两个数组并在无序列表中列出NON匹配

时间:2012-10-23 10:03:19

标签: php arrays multidimensional-array array-difference

我有两个数组,我需要找到两者之间的差异,并将它们显示在无序列表中。

我可以循环访问主数组以进行单个匹配,但我不知道如何在主列表中循环以获取多个键值并有效地执行此操作。

以下是每个数组的关键值摘录:

要搜索的主数组

foreach ( $levels as $level ) {
  $output .= '<li>' . $level['name'] . '</li>';

包含可能匹配的数组

foreach ( $login_member_levels as $level ) {
  $output .= '<li>' . $level_array[]=$level->level . '</li>';

添加了多维问题的信息...

以下是我需要比较的两个多维数组,但子数组不匹配:

我需要比较第一个数组[levels] [level_id]和[levels] [level] [id]

Array
(
  [success] => 1
  [member] => Array
    (
      [0] => Array
        (
          [ID] => 2
          [UserInfo] => Array
              (
                 [ID] => 2
                 [caps] => Array
                      (
                          [administrator] => 1
                      )
              )
          [Sequential] => 
          [Levels] => Array
            (
                [1347037874] => stdClass Object
                    (
                       [Level_ID] => 1347037874
                       [Name] => HFM-Cardiac Resistance Training Program
                       [Cancelled] => 
                    )

                [1347037875] => stdClass Object
                   (
                       [Level_ID] => 1347037875
                       [Name] => HFM-Official Heart Health Guide
                       [Cancelled] => 
                       [1347037876] => stdClass Object
                       (
                             [Level_ID] => 1347037876
                             [Name] => HFM-All Access Cardiac Success Club
                         [Cancelled] => 
                            )
                    )
        )
    )   

这是第二个数组:

Array
(
    [success] => 1
    [levels] => Array
        (
            [level] => Array
                (
                    [0] => Array
                        (
                            [id] => 1347037871
                            [name] => HFM-Ask the Experts
                            [_more_] => /levels/1347037871
                        )
                    [1] => Array
                        (
                            [id] => 1347037874
                            [name] => HFM-Cardiac Resistance Training Program
                            [_more_] => /levels/1347037874
                        )
                    [2] => Array
                        (
                            [id] => 1347037875
                            [name] => HFM-Official Heart Health Guide
                            [_more_] => /levels/1347037875
                        )
                    [3] => Array
                        (
                            [id] => 1347037876
                            [name] => HFM-All Access Cardiac Success Club
                            [_more_] => /levels/1347037876
                        )
                )
        )
   [supported_verbs] => Array
        (
           [0] => GET
           [1] => POST
        )
)

2 个答案:

答案 0 :(得分:2)

请注意,正如Jod正确建议的那样,array_diff函数会将array1 array2进行比较并返回差异。
例如:

$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "brown");
$result = array_diff($array1, $array2);

var_dump($array1);
var_dump($array2);
var_dump($result);

会给你:

// Array1
array(4) {
  [0] => "green"
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

// Array2
array(3) {
  [0] => "green"
  [1] => "yellow"
  [2] => "brown"
}

// array_diff result
array(3) {
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

因为它们是array1中存在的值但不是array2中的值
如果您有兴趣获取一个包含 两个(或多个)数组之间所有差异(作为值) 的数组,我为此编写了一个函数:

function array_diff_all()
{
    $arguments = func_get_args();

    $merged         = array();    
    $intersected    = $arguments[0];
    for ($i = 0; $i < count($arguments); $i++)
    {
        $merged         = array_merge($merged, $arguments[$i]);
        $intersected    = array_intersect($intersected, $arguments[$i]);
    }

    return array_values(array_filter( array_unique(array_diff($merged, $intersected)) ));
}

使用示例:(与之前相同)

$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "brown");
$result = array_diff_all($array1, $array2);

var_dump($array1);
var_dump($array2);
var_dump($result);

会给你

// Array1
array(4) {
  [0] => "green"
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

// Array2
array(3) {
  [0] => "green"
  [1] => "yellow"
  [2] => "brown"
}

// array_diff_all result
array(4) {
  [0] => "red"
  [1] => "blue"
  [2] => "yellow"
  [3] => "brown"
}

请注意:
1)它仅适用于索引数组,如果使用散列(关联数组),只有当键是唯一的时才能正常工作。
2)对结果数组进行重新索引,这意味着一个值与原始值相比可以有不同的索引 3)删除重复值并返回唯一的结果数组 4)您可以一次比较多个阵列 例如:

$first  = array('foo', 'moo', 'zoo');
$second = array('foo', 'done', 'gone');
$third  = array('foo', 'mix', 'zoo');

var_dump( array_diff_all($first, $second, $third) );

将输出:

array(5) {
  [0] => "moo"
  [1] => "zoo"
  [2] => "done"
  [3] => "gone"
  [4] => "mix"
}

修改
对于你的问题的第二部分:
您不能在特定情况下使用上述方法,因为您有两个完全不同的数组可供比较,而且第一个数组包含对象。
要解决您的问题,您需要:
A)了解如何访问第一个数组的“levels”数组。在我看来,你必须迭代$ array1 ['member'],我猜每个都有一个'levels'数组。 它可以是:

foreach ($array1['member'] as $member)
{
    $levels = $member['levels'];
    ...
}

此时$ level应该是一个对象数组,如:

[Levels] => Array
    (
        [1347037874] => stdClass Object
            (
        [Level_ID] => 1347037874
        [Name] => HFM-Cardiac Resistance Training Program
        [Cancelled] => 
    )

    [1347037875] => stdClass Object
    (
                [Level_ID] => 1347037875
        [Name] => HFM-Official Heart Health Guide
        [Cancelled] => 
            )

    [1347037876] => stdClass Object
    (
        [Level_ID] => 1347037876
            [Name] => HFM-All Access Cardiac Success Club
        [Cancelled] => 
            )
    )

B)这个想法是要注意你需要比较的level_id是这个'levels'数组的关键,而array2是'普通的'多维数组(我的意思是不包含对象) )..所以我们可以安全地使用php的内置数组函数 我们可以假设level_id非常复杂,在$ array2中是唯一的,所以我们只能检查某个level_id是否存在 (递归地)$ array2作为价值,无需比较其中的'id'键
要做到这一点,你需要:
C)我写的递归in_array函数:

function in_array_recursive($needle, $haystack)
{ 

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack)); 

    foreach ($it AS $element)
        if ($element === $needle)
            return true; 

    return false; 
}


D)创建一个帮助器,用作array_filter的回调函数

function array_diff_helper($var)
{
    global $array2;
    return !(in_array_recursive(trim($var), $array2));
}

请注意如果不同,请在此处使用您的第二个阵列的名称。
E)最后,您可以获得level_ids的差异:

$diff = array_filter(array_keys($levels), "array_diff_helper");



所以.. 你需要的循环可能就像那样简单:

foreach ($array1['member'] as $member)
{
    $not_matching_ids = array_filter(array_keys($member['levels']), "array_diff_helper");
}

希望这会有所帮助,欢呼! :)

答案 1 :(得分:1)

使用array_diff()生成一组不匹配的值。

http://php.net/manual/en/function.array-diff.php