PHP - ตรวจสอบว่ามีสองอาร์เรย์เท่ากันหรือไม่


280

ฉันต้องการตรวจสอบว่ามีสองอาร์เรย์เท่ากันหรือไม่ ฉันหมายถึง: ขนาดเดียวกันดัชนีเดียวกันค่าเดียวกัน ฉันจะทำสิ่งนั้นได้อย่างไร

การใช้!==ตามที่ผู้ใช้แนะนำฉันคาดหวังว่าสิ่งต่อไปนี้จะพิมพ์Enterหากอย่างน้อยหนึ่งองค์ประกอบในอาร์เรย์นั้นแตกต่างกัน แต่อันที่จริงแล้วมันไม่ได้

if (($_POST['atlOriginal'] !== $oldAtlPosition) 
    or ($_POST['atl'] !== $aext) 
    or ($_POST['sidesOriginal'] !== $oldSidePosition) 
    or ($_POST['sidesOriginal'] !== $sideext)) {

    echo "enter";
}

17
คุณกำลังใช้งาน=มากเกินไปควรจะเป็น!==หรือ!=
jeroen

29
เพียงแค่สำหรับบันทึก (ตั้งแต่การแก้ไขของฉันได้เปลี่ยนกลับไปเป็น "ผู้ใช้") มันคือ "ผู้ใช้": english.stackexchange.com/questions/105116/...
teynon

7
['a'] == [0]trueเป็น นี่เป็นเพียง PHP
DávidHorváth

2
@ DávidHorváthมันแปลกจริง ๆ มันเป็นการใช้งานที่ดีเสมอ ===
AFA Med

1
@ DávidHorváthการเปรียบเทียบแบบหลวมนั้นไม่เพียง แต่ในภาษา PHP เท่านั้น ถ้าคุณมอง JS คุณจะประหลาดใจ อย่าใช้จนกว่าคุณจะเข้าใจสิ่งที่ดีกว่า
ryabenko-pro

คำตอบ:


508
$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs.
$arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types.

ดูผู้ประกอบการอาร์เรย์

แก้ไข

ผู้ประกอบการไม่เท่าเทียมกันคือ!=ในขณะที่ผู้ประกอบการที่ไม่ใช่ตัวตนคือ!==เพื่อให้ตรงกับผู้ประกอบการที่เท่าเทียมกันและผู้ประกอบการตัวตน=====


79
หมายเหตุด้านข้าง: วิธีนี้ใช้ได้กับอาร์เรย์หลายมิติเช่นกัน (มันไม่ชัดเจนสำหรับฉันมาก่อน)
trejder

5
PS: วิธีการแก้ปัญหาคือการใช้array_values($a)==array_values($b)... array_unique()อีกปัญหาที่ปกติเป็นเรื่องเกี่ยวกับค่าที่ไม่ซ้ำกันเพื่อให้จำที่มีอยู่ว่า
Peter Krauss

13
คำตอบนี้ผิด ทำงานโดยไม่คำนึงถึงการสั่งซื้อเพียงสำหรับพจนานุกรมทั่วไปเช่น== เพื่อยกตัวอย่างเช่น[1 => 'a', 2 => 'b'] [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']สำหรับอาร์เรย์ที่จัดทำดัชนีเช่น['a', 'b'] ==ไม่ทำงานตามที่ระบุไว้ ['a', 'b'] != ['b', 'a']เพื่อยกตัวอย่างเช่น
nawfal

37
@nawfal: สมมติฐานของคุณผิด ['a', 'b']เป็นอาร์เรย์[0 => 'a', 1 => 'b']ในขณะที่ เป็นอาร์เรย์['b', 'a'] [0 => 'b', 1 => 'a']นั่นเป็นเหตุผลที่พวกเขาไม่มีคู่คีย์ / ค่าเดียวกันตามที่ระบุไว้ในคำตอบของฉันและนั่นเป็นเหตุผลที่==ไม่ทำงานระหว่างพวกเขา
Stefan Gehrig

29
@StefanGehrig โอ้คุณพูดถูก ฉันจะออกความคิดเห็นของฉันเป็นเช่นนี้จะทำให้ความโง่เขลาของฉันชัด :)
Nawfal

88

ตามหน้านี้

หมายเหตุ:คำตอบที่ยอมรับใช้งานได้สำหรับอาร์เรย์ที่เชื่อมโยง แต่จะไม่ทำงานตามที่คาดไว้กับอาร์เรย์ที่มีการจัดทำดัชนี (อธิบายไว้ด้านล่าง) หากคุณต้องการเปรียบเทียบอย่างใดอย่างหนึ่งจากนั้นใช้โซลูชันนี้ นอกจากนี้ฟังก์ชันนี้อาจไม่ทำงานกับอาร์เรย์หลายมิติ (เนื่องจากลักษณะของฟังก์ชัน array_diff)

การทดสอบอาร์เรย์ที่ทำดัชนีสองชุดซึ่งองค์ประกอบใดอยู่ในลำดับที่แตกต่างกันการใช้$a == $bหรือ$a === $bล้มเหลวตัวอย่างเช่น

<?php
    (array("x","y") == array("y","x")) === false;
?>

นั่นเป็นเพราะข้างต้นหมายถึง:

array(0 => "x", 1 => "y")กับarray(0 => "y", 1 => "x").

ในการแก้ปัญหาดังกล่าวให้ใช้:

<?php
function array_equal($a, $b) {
    return (
         is_array($a) 
         && is_array($b) 
         && count($a) == count($b) 
         && array_diff($a, $b) === array_diff($b, $a)
    );
}
?>

การเปรียบเทียบขนาดอาร์เรย์ถูกเพิ่ม (แนะนำโดย super_ton) เนื่องจากอาจปรับปรุงความเร็ว


2
ข้อควรระวัง: ใช้งานไม่ได้ตามที่คาดไว้กับอาร์เรย์หลายมิติ
maersu

8
ความคิดเห็นข้างต้นเป็นเท็จ ถ้า $ b มีองค์ประกอบทั้งหมด $ a ได้บวกกับบางส่วนเพิ่มเติมทั้งสองอาร์เรย์จะไม่เท่ากันรหัสข้างต้นจะบอกว่าพวกเขาเป็น
Ghola

1
อาจมีค่าเพิ่มการนับ ($ a) == count ($ b) ด้วย
stefan

1
@super_ton: ใช่ก่อนที่จะโทรarray_diffสามารถเร่งการเปรียบเทียบ ฉันจะเพิ่ม ขอบคุณ
lepe

3
น่าเสียดายที่มันใช้งานไม่ได้ในบางกรณีเช่นฉันได้ทดสอบด้วยเคสต่อไปนี้$a = [1, 2, 2]; $b = [2, 1, 1];และมันกลับมาtrueแต่ทั้งสองอาร์เรย์ไม่เหมือนกัน
AwesomeGuy

33

ลองทำให้เป็นอันดับ นี้จะตรวจสอบ subarrays ซ้อนเช่นกัน

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";

7
มีปัญหาหากปุ่มและค่าต่าง ๆ เลื่อนไปมาเหมือนการใช้การเปรียบเทียบ อย่างไรก็ตามสมมติว่าพวกเขาคาดว่าจะเหมือนกัน 100% นี่เป็นวิธีที่สะอาดและง่ายที่สุดในการตรวจสอบความเท่าเทียมกันอย่างลึกล้ำ!
Kevin Peno

1
ฉันเดาว่านี่เป็นทางออกที่ดีที่สุด! มันสามารถเปรียบเทียบอาร์เรย์หลายมิติและเชื่อมโยงหากพวกเขาถูกจัดเรียงก่อนหน้านี้!
Rafael Moni

13

วิธีการแก้ปัญหาแบบสั้นที่ทำงานได้แม้กับอาร์เรย์ที่คีย์ได้รับตามลำดับที่แตกต่างกัน

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}

3
อาจเป็นคำตอบที่ดีที่สุดคำตอบส่วนใหญ่อาจไม่ตรงกันหากปุ่มถูกเลื่อนหรือเป็นอาร์เรย์หลายมิติ
AwesomeGuy

11

เปรียบเทียบเป็นค่าอื่น ๆ :

if($array_a == $array_b) {
  //they are the same
}

คุณสามารถอ่านเกี่ยวกับตัวดำเนินการอาร์เรย์ทั้งหมดได้ที่นี่: http://php.net/manual/en/language.operators.array.php หมายเหตุสำหรับตัวอย่างที่===ตรวจสอบประเภทและลำดับขององค์ประกอบในอาร์เรย์ด้วย


5
หรือ===ขึ้นอยู่กับพฤติกรรมที่ต้องการ
Matthew Flaschen

9

!===จะไม่ทำงานเพราะมันเป็นข้อผิดพลาดทางไวยากรณ์ วิธีที่ถูกต้องคือ!==(ไม่สามสัญลักษณ์ "เท่ากับ")


5
if (array_diff($a,$b) == array_diff($b,$a)) {
  // Equals
}

if (array_diff($a,$b) != array_diff($b,$a)) {
  // Not Equals
}

จากมุมมองของฉันจะดีกว่าการใช้ array_diff กว่า array_intersect เพราะด้วยการตรวจสอบลักษณะนี้ความแตกต่างที่กลับมาโดยทั่วไปมีค่าน้อยกว่าความคล้ายคลึงกันวิธีนี้การแปลงแบบบูลนั้นกำลังหิวหน่วยความจำน้อยกว่า

แก้ไขโปรดทราบว่าโซลูชันนี้มีไว้สำหรับอาร์เรย์ธรรมดาและเติมเต็ม == และ === หนึ่งโพสต์ข้างต้นที่ใช้ได้สำหรับพจนานุกรมเท่านั้น


4

array_diff - คำนวณความแตกต่างของอาร์เรย์

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

array array_diff ( array $array1 , array $array2 [, array $... ] )

เปรียบเทียบarray1กับหนึ่งหรือสองอาร์เรย์อื่น ๆ และส่งกลับค่าในarray1ที่ไม่ได้อยู่ในใด ๆ ของอาร์เรย์อื่น ๆ


4
OP ต้องการ "ตรวจสอบว่ามีสองอาร์เรย์เท่ากันหรือไม่" array_diffไม่สามารถบอกคุณได้ ลองarray_diff([1, 2], [1, 2, 'hello'])ดู
marcv

3

วิธีการอื่นในการตรวจสอบความเท่าเทียมกันโดยไม่คำนึงถึงลำดับของมูลค่าทำงานโดยใช้http://php.net/manual/en/function.array-intersect.phpเช่นนั้น:

$array1 = array(2,5,3);
$array2 = array(5,2,3);
if($array1 === array_intersect($array1, $array2) && $array2 === array_intersect($array2, $array1)) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

นี่คือเวอร์ชันที่ใช้งานได้กับอาเรย์หลายมิติโดยใช้http://php.net/manual/en/function.array-uintersect.php :

$array1 = array(
    array(5, 2),
    array(3, 6),
    array(2, 9, 4)
);
$array2 = array(
    array(3, 6),
    array(2, 9, 4),
    array(5, 2)
);

if($array1 === array_uintersect($array1, $array2, 'compare') && $array2 === array_uintersect($array2, $array1, 'compare')) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

function compare($v1, $v2) {
    if ($v1===$v2) {
        return 0;
    }
    if ($v1 > $v2) return 1;
    return -1;
}

3
function compareIsEqualArray(array $array1,array $array):bool
{

   return array_diff($array1,$array2)==[];

}

2
เป็นประโยชน์ในการอธิบายว่าตัวอย่างโค้ดกำลังทำอะไร สิ่งนี้สามารถใช้งานกับอาร์เรย์หลายมิติได้หรือไม่
k0pernikus

1
array_diff รับองค์ประกอบที่แตกต่างจาก array หาก array_diff ส่งคืนอาเรย์ที่ว่างเปล่าสองอาร์เรย์มีค่าเท่ากัน
dılosürücü

2

วิธีหนึ่ง: (การใช้ 'ถือว่าเท่าเทียมกันสำหรับhttp://tools.ietf.org/html/rfc6902#section-4.6 )

วิธีนี้ช่วยให้อาเรย์เชื่อมโยงซึ่งสมาชิกได้รับคำสั่งแตกต่างกัน - เช่นพวกเขาได้รับการพิจารณาเท่าเทียมกันในทุกภาษายกเว้น php :)

// recursive ksort
function rksort($a) {
  if (!is_array($a)) {
    return $a;
  }
  foreach (array_keys($a) as $key) {
    $a[$key] = ksort($a[$key]);
  }
  // SORT_STRING seems required, as otherwise
  // numeric indices (e.g. "0") aren't sorted.
  ksort($a, SORT_STRING);
  return $a;
}


// Per http://tools.ietf.org/html/rfc6902#section-4.6
function considered_equal($a1, $a2) {
  return json_encode(rksort($a1)) === json_encode(rksort($a2));
}

1
ผมเชื่อว่าคุณก็ควรจะ:$a[$key] = rksort($a[$key]);
pinkeen

2

ปัญหาไวยากรณ์ในอาร์เรย์ของคุณ

$array1 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$diff = array_diff($array1, $array2);

var_dump($diff); 

2

นี่คือตัวอย่างวิธีการเปรียบเทียบกับอาร์เรย์และรับสิ่งที่แตกต่างระหว่างพวกเขา

$array1 = ['1' => 'XXX', 'second' => [
            'a' => ['test' => '2'],
            'b' => 'test'
        ], 'b' => ['no test']];

        $array2 = [
            '1' => 'XX',
            'second' => [
                'a' => ['test' => '5', 'z' => 5],
                'b' => 'test'
            ],
            'test'
        ];


        function compareArrayValues($arrayOne, $arrayTwo, &$diff = [], $reversed = false)
        {
            foreach ($arrayOne as $key => $val) {
                if (!isset($arrayTwo[$key])) {
                    $diff[$key] = 'MISSING IN ' . ($reversed ? 'FIRST' : 'SECOND');
                } else if (is_array($val) && (json_encode($arrayOne[$key]) !== json_encode($arrayTwo[$key]))) {
                    compareArrayValues($arrayOne[$key], $arrayTwo[$key], $diff[$key], $reversed);
                } else if ($arrayOne[$key] !== $arrayTwo[$key]) {
                    $diff[$key] = 'DIFFERENT';
                }
            }
        }

        $diff = [];
        $diffSecond = [];

        compareArrayValues($array1, $array2, $diff);
        compareArrayValues($array2, $array1, $diffSecond, true);

        print_r($diff);
        print_r($diffSecond);

        print_r(array_merge($diff, $diffSecond));

ผลลัพธ์:

Array
(
    [0] => DIFFERENT
    [second] => Array
        (
            [a] => Array
                (
                    [test] => DIFFERENT
                    [z] => MISSING IN FIRST
                )

        )

    [b] => MISSING IN SECOND
    [1] => DIFFERENT
    [2] => MISSING IN FIRST
)

1

ใช้ฟังก์ชั่น php array_diff (array1, array2);

มันจะคืนความแตกต่างระหว่างอาร์เรย์ ถ้ามันว่างเปล่ามันก็เท่ากับ

ตัวอย่าง:

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3'
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value4'
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print array = (0 => ['c'] => 'value4' ) 

ตัวอย่างที่ 2:

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print empty; 

1
ในทางเทคนิคแล้วจะไม่ส่งคืนความแตกต่างระหว่างอาร์เรย์ เอกสารประกอบระบุ "เปรียบเทียบ array1 กับอาร์เรย์อื่นหนึ่งตัวขึ้นไปและส่งกลับค่าใน array1 ที่ไม่ได้อยู่ในอาร์เรย์อื่นใด ๆ " ดังนั้นถ้าค่าทั้งหมดจาก array1 มีอยู่ใน array2 แม้ว่า array2 จะมีค่ามากกว่า array_diff จะส่งคืนอาร์เรย์ว่าง
2pha

ไม่ "พิมพ์ว่าง" พิมพ์อาร์เรย์ว่าง (หลังจากแก้ไขข้อผิดพลาดทางไวยากรณ์โหล) บางทีคุณอาจใช้(count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0ในการทดสอบว่าอาร์เรย์มีค่าเท่ากันหรือไม่
user9645

ฉันแก้ไขไวยากรณ์ (ไม่ว่างเปล่าและฉันผสมจุลภาค -. -) สิ่งที่คุณเสนอฉันคิดว่ามากเกินไป ตรวจสอบว่าอาร์เรย์ที่ว่างเปล่าควรเพียงพอหรือไม่
Wolfgang Leon

1

หากคุณต้องการตรวจสอบอาร์เรย์ที่ไม่เชื่อมโยงนี่คือวิธีแก้ปัญหา:

$a = ['blog', 'company'];
$b = ['company', 'blog'];

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.