İki dizinin eşit olup olmadığını kontrol edin


280

İki dizinin eşit olup olmadığını kontrol etmek istiyorum. Yani: aynı boyut, aynı indeks, aynı değerler. Bunu nasıl yapabilirim?

!==Bir kullanıcı tarafından önerildiği gibi kullanarak , dizi (ler) en az bir öğe farklı, ama aslında değil, enter girin yazdırmak bekliyoruz .

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

    echo "enter";
}

17
=Çok fazla kullanıyorsunuz , !==ya da olmalıdır!=
jeroen

29
Sadece kayıt için (düzenlemem tekrar "bir kullanıcı" olarak değiştirildiğinden) "bir kullanıcı": english.stackexchange.com/questions/105116/…
teynon

7
['a'] == [0]olduğunu true. Bu sadece PHP.
Dávid Horváth

2
@ DávidHorváth gerçekten tuhaf, her zaman kullanmak için iyi bir uygulama ===
AFA Med

1
@ DávidHorváth, gevşek karşılaştırma sadece PHP'de gevşek değil. JS'ye bakarsanız şaşıracaksınız. Sadece daha iyi anlayana kadar kullanmayın.
ryabenko-pro

Yanıtlar:


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.

Bkz. Dizi İşleçleri .

DÜZENLE

Eşitsizlik operatörü, !=kimlik olmayan operatör !==eşitlik operatörü ==ve kimlik operatörü ile eşleşmelidir ===.


79
Bir yan not: Bu yaklaşım çalışır (daha önce benim için bariz değildi) sıra çok boyutlu diziler için.
trejder

5
PS: çözüm kullanmaktır array_values($a)==array_values($b)... Bir diğer olağan sorun benzersiz değerler hakkında, bu yüzden var olduğunu unutmayın array_unique().
Peter Krauss

13
Bu cevap yanlış. ==sıradan bağımsız olarak sadece tipik sözlükler için çalışır [1 => 'a', 2 => 'b']. Örneğin [1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']. Endeksli diziler için olduğu gibi ['a', 'b'] ==çalışmaz. Örneğin ['a', 'b'] != ['b', 'a'].
nawfal

37
@nawfal: Varsayımınız yanlış. ['a', 'b']bir dizi [0 => 'a', 1 => 'b'], ['b', 'a']bir dizi [0 => 'b', 1 => 'a']. Bu yüzden cevabımda belirtilen anahtar / değer çiftlerine ==sahip değiller ve bu yüzden bunlar arasında çalışmıyorlar.
Stefan Gehrig


88

Bu sayfaya göre .

NOT: Kabul edilen cevap ilişkilendirilebilir diziler için çalışır, ancak dizinlenmiş dizilerle beklendiği gibi çalışmaz (aşağıda açıklanmıştır). Her ikisini de karşılaştırmak istiyorsanız, bu çözümü kullanın. Ayrıca, bu işlev çok boyutlu dizilerle (array_diff işlevinin doğası gereği) çalışmayabilir.

İki dizinlenmiş dizinin test edilmesi, hangi öğelerin farklı sırayla olduğu, kullanılarak $a == $bveya $a === $bbaşarısız olması, örneğin:

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

Çünkü yukarıdakiler şu anlama gelir:

array(0 => "x", 1 => "y")vs array(0 => "y", 1 => "x").

Bu sorunu çözmek için şunu kullanın:

<?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)
    );
}
?>

Hızı artırabileceğinden dizi boyutlarının karşılaştırılması (super_ton tarafından önerilir) eklendi.



8
Yukarıdaki yorum yanlıştır. $ B, $ a öğesinin tüm artılarına ve bazı ekstra öğelere sahipse, iki dizi eşit değildir, ancak yukarıdaki kod olduklarını söyleyecektir.
Ghola

1
sayı ($ a) == sayı ($ b) da eklemeye değer olabilir
stefan

1
@super_ton: evet, arama yapmadan önce array_diffkarşılaştırmayı hızlandırabilir. Ben ekleyeceğim. Teşekkürler
lepe

3
Ne yazık ki, bazı durumlarda işe yaramaz, örneğin, aşağıdaki durumla test ettim $a = [1, 2, 2]; $b = [2, 1, 1];ve geri döndü true, ancak iki dizi açıkça aynı değil.
AwesomeGuy

33

Serileştirmeyi deneyin. Bu, iç içe alt dizileri de kontrol edecektir.

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

7
Anahtarlar ve değerler tıpkı karşılaştırma gibi kaydırılırsa sorunludur. Bununla birlikte,% 100 aynı olmaları beklenirse, derin eşitliği kontrol etmenin en temiz ve en kolay yolu budur!
Kevin Peno

1
Sanırım bu en iyi çözüm! Daha önce sıralandıklarında çok boyutlu ve ilişkilendirilebilir dizileri karşılaştırabilir!
Rafael Moni

13

Hangi anahtarların farklı sırada verildiği dizilerde bile çalışan kısa çözüm:

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

3
Muhtemelen şimdiye kadarki en iyi cevap, anahtarların değiştirilmesi durumunda veya çok boyutlu bir dizi ise cevapların çoğu uyuşmuyor.
AwesomeGuy


9

!===sözdizimi hatası olduğu için çalışmaz. Doğru yol !==(üç "eşit" sembolü değildir)


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

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

Benim pov dan array_diff kullanmak array_intersect daha iyidir çünkü bu doğanın kontrolleri ile sık sık döndürülen farklılıklar benzerliklerden daha azdır, bu şekilde bool dönüşüm daha az bellek açtır.

Düzenle Bu çözümün düz diziler için olduğunu ve yukarıda gönderilen ve yalnızca sözlükler için geçerli olan == ve === birini tamamladığını unutmayın.


4

array_diff - Diziler arasındaki farkı hesaplar

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

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

array1Bir veya daha fazla diğer diziyle karşılaştırır ve diğer dizilerin array1hiçbirinde bulunmayan değerleri döndürür .


4
OP "iki dizinin eşit olup olmadığını kontrol etmek" istiyor. array_diffbunu sana söyleyemem. Deneyin array_diff([1, 2], [1, 2, 'hello']).
marcv

3

Değer sırasına bakılmaksızın eşitliği kontrol etmek için başka bir yöntem http://php.net/manual/en/function.array-intersect.php kullanarak çalışır :

$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 kullanarak çok boyutlu dizilerle de çalışan bir sürüm :

$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
Bir kod örneğinin ne yaptığını açıklamak faydalıdır. Bu çok boyutlu diziler için de geçerli mi?
k0pernikus

1
array_diff dizi boş dizisini döndürürse
dizi_diff

2

Bir yol: ( http://tools.ietf.org/html/rfc6902#section-4.6 için 'eşit kabul edildi' uygulaması )

Bu şekilde üyeleri farklı şekilde sıralanan ilişkilendirilebilir dizilere izin verilir - örneğin php hariç her dilde eşit kabul edilirler :)

// 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
Ben olması gerektiğini düşünüyorum:$a[$key] = rksort($a[$key]);
pinkeen

2

Dizilerinizde sözdizimi sorunu

$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

Dizilerle nasıl karşılaştırılacağı ve aralarında farklı olanın nasıl alınacağına dair örnek.

$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));

Sonuç:

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

        )

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

1

Dizi_diff (dizi1, dizi2) php işlevini kullanın;

Diziler arasındaki farkı döndürür. Eğer boşsa, o zaman eşittirler.

misal:

$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' ) 

Örnek 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
Teknik olarak, diziler arasındaki farkı döndürmez. Belgeler "dizi1'i bir veya daha fazla diğer diziyle karşılaştırır ve dizi1'deki diğer dizilerin hiçbirinde bulunmayan değerleri döndürür." Bu nedenle,
dizi1'deki tüm

"Null yazdır" yapmaz, boş bir dizi yazdırır (yaklaşık bir düzine sözdizimi hatasını düzelttikten sonra). Belki de (count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0dizilerin "eşit" olup olmadığını test etmek için kullanabilirsiniz
user9645

Sözdizimini düzelttim (boş değil, virgül -.- karıştırıyordum). Teklif ettiğin şeyin çok fazla olduğunu düşünüyorum. Boş bir dizinin yeterli olup olmadığını kontrol etmek.
Wolfgang Leon

1

İlişkisel olmayan dizileri kontrol etmek istiyorsanız, işte çözüm:

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

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.