2015-11-29 18 views
0

我有兩個數組我想比較:如何比較兩個數組並顯示每個鍵(多維數組)的差異?

animals1:

array(4) { 
    ["1234"]=> 
    array(5) { 
    ["animal"]=> 
    string(19) "cat" 
    ["name"]=> 
    string(12) "fred" 
    ["food"]=> 
    string(32) "milk" 
    } 
    ["5678"]=> 
    array(5) { 
    ["animal"]=> 
    string(19) "dog" 
    ["name"]=> 
    string(12) "sam" 
    ["food"]=> 
    string(32) "chicken" 
    } 
    ["shop"]=> 
    string(12) "petcenter" 
} 

animals2:

array(4) { 
    ["1234"]=> 
    array(5) { 
    ["animal"]=> 
    string(19) "cat" 
    ["name"]=> 
    string(12) "tom" 
    ["food"]=> 
    string(32) "juice" 
    } 
    ["5678"]=> 
    array(5) { 
    ["animal"]=> 
    string(19) "dog" 
    ["name"]=> 
    string(12) "sam" 
    ["food"]=> 
    string(32) "fish" 
    } 
    ["shop"]=> 
    string(12) "petcenter" 
} 

這裏是我的代碼:

foreach ($animals1 as $k1 => $v1) { 
    if (array_diff($animals2[$k1], $animals1[$k1])){ 
     $diff[$k1] = array_diff($animals2[$k1], $animals1[$k1]); 
    } 
} 
foreach ($animals2 as $k1 => $v1) { 
    if (array_diff($animals1[$k1], $animals2[$k1])){ 
     $diff2[$k1] = array_diff($animals1[$k1], $animals2[$k1]); 
    } 
} 
function result1($item, $key){ 
    echo $key."1 = ".$item; 
    echo "<br>"; 
} 
function result2($item, $key){ 
    echo $key."2 = ".$item; 
    echo "<br>"; 
} 
foreach ($diff as $d => $key){ 

    foreach ($animals1 as $p => $row) { 
      if ($p == $d){ 
        echo "Error for animal".$row["animal"]; 
        echo "with the name:".$row["name"]."."; 
      } 
     } 
} 
array_walk_recursive($diff, 'result1'); 
array_walk_recursive($diff2, 'result2'); 

我的結果是:

Error for animal cat with name fred. 
Error for animal dog with name sam. 

name1 = fred 
food1 = milk 
food1 = chicken 

name2 = tom 
food2 = juice 
food2 = fish 

但我需要的是:

Error for animal cat with name fred. 

name1 = fred 
name2 = tom 

food1 = milk 
food2 = juice 

Error for animal dog with name sam. 

food1 = chicken 
food2 = fish 

這意味着,首先我要顯示存在具有特定名稱的特定動物的錯誤。在此之後,我想顯示差異。那意味着始終爲animal1的值,之後的值爲animal2。 我不知道如何改變我的代碼,以達到我想要的效果。


這是Standej的輸出:

Error for animal cat with name fred. 

name1 = fred 
food1 = milk 
food1 = chicken 

name2 = tom 
food2 = juice 
food2 = fish 

Error for animal dog with name sam. 

name1 = fred 
food1 = milk 
food1 = chicken 

name2 = tom 
food2 = juice 
food2 = fish 
+1

[PHP 2點多維數組差(的可能的複製http://stackoverflow.com/questions/27856743/ php-two-multidimensional-array-difference) –

+0

@Elias Nicolas我需要以不同的方式比較不同的密鑰 – Jarla

+0

如果使用'array_diff'則會導致奇怪的結果,如果一個cat的'name'值等於其他貓,反之亦然。 – trincot

回答

1

嘗試,如果你想重新排序結果

foreach ($animals1 as $k1 => $v1) { 
    if (array_diff($animals2[$k1], $animals1[$k1])){ 
     $diff[$k1] = array_diff($animals2[$k1], $animals1[$k1]); 
    } 
} 
foreach ($animals2 as $k1 => $v1) { 
    if (array_diff($animals1[$k1], $animals2[$k1])){ 
     $diff2[$k1] = array_diff($animals1[$k1], $animals2[$k1]); 
    } 
} 
function result1($item, $key){ 
    echo $key."1 = ".$item; 
    echo "<br>"; 
} 
function result2($item, $key){ 
    echo $key."2 = ".$item; 
    echo "<br>"; 
} 
foreach ($diff as $d => $key){ 

    foreach ($animals1 as $p => $row) { 
      if ($p == $d){ 
        echo "Error for animal".$row["animal"]; 
        echo "with the name:".$row["name"]."."; 
// Put your functions inside loop where you printing errors 
        array_walk_recursive($diff, 'result1'); 
        array_walk_recursive($diff2, 'result2'); 
// End of change 
      } 
     } 
} 

希望它會工作

+0

謝謝,但我沒有得到我需要的輸出。我在我的問題中發佈了答案的結果。 – Jarla

+0

我有一個問題。你必須使用array_walk_recursive,或者我可以嘗試以不同的方式寫你的結果,而不使用這個函數? @Jarla – Standej

+0

我很高興爲結果的每一種方式:)不需要被array_walk_recursive – Jarla

0

問題使用重新排序代碼array_diff是它只比較值而不是鍵,所以你可能無法檢測到一個dif如果一隻貓的名字等於另一隻貓的名字,反之亦然。

使用array_diff_assoc也是比較密鑰的改進。

儘管如此,代碼仍然會遺漏一些不同之處,比如第一隻動物缺少關鍵字時,沒有food$diff數組不會有這種差異,並且由於代碼迭代超過$diff,如果所有其餘數相等,相應的動物將不會包含在輸出中。

原始代碼還假定animalname鍵總是在那裏。

下面是一些代碼,應該工作,即使某些項丟失任何一方:

function outputDiff($animals1, $animals2) { 
    foreach($animals1 as $key => $animal1) { 
     // skip animals that only exist in one of the two arrays 
     if (!is_array($animal1) || !isset($animals2[$key])) continue; 
     $animal2 = $animals2[$key]; 
     if (!is_array($animal2)) continue; 
     // add "animal" and "name" keys to first animal when they are missing 
     $animal1 = array_merge(array("animal"=>"(unknown)","name"=>"(unknown)"), 
        $animal1); 
     // collect the keys that either animal has: 
     $properties = array_unique(array_merge(
         array_keys($animal1), array_keys($animal2))); 
     $equal = true; 
     foreach ($properties as $property) { 
      // get values from both sides, default to '(unknown)' 
      $value1 = isset($animal1[$property]) ? $animal1[$property] : '(unknown)'; 
      $value2 = isset($animal2[$property]) ? $animal2[$property] : '(unknown)'; 
      if ($value1 !== $value2) { 
       if ($equal) { 
        // display header 
        echo "<h4>Error for animal {$animal1['animal']}" . 
           "with name {$animal1['name']}</h4>"; 
        $equal = false; 
       } 
       // display detail 
       echo "<p>{$property}1 = $value1<br>"; 
       echo "{$property}2 = $value2</p>"; 
      } 
     } 
    } 
} 

// Set-up test data 
$animals1 = array(
    "1234"=>array(
    "animal"=>"cat", 
    "name"=>"fred", 
    "food"=>"milk" 
), 
    "5678"=>array(
    "animal"=>"dog", 
    "name"=>"sam", 
    "food"=>"chicken" 
), 
    "8888"=>array(
    "animal"=>"cow", 
    "name"=>"freddy", 
    "food"=>"grass" 
), 
    "shop"=>"petcenter" 
); 
$animals2 = array(
    "1234"=>array(
    "animal"=>"cat", 
    "name"=>"tom", 
    "food"=>"juice" 
), 
    "5678"=>array(
    "animal"=>"dog", 
    "name"=>"sam", 
    "food"=>"fish" 
), 
    "shop"=>"petcenter" 
); 

// Perform test 
outputDiff($animals1, $animals2); 

此代碼輸出html標籤(除去他們,如果他們打擾你)。上述的輸出是:

誤差動物貓名稱fred的

NAME1 = fred的

NAME2 =湯姆

食物1 =牛奶

FOOD2 =汁

呃ROR動物的狗與名稱SAM

食物1 =雞

FOOD2 =魚