현재 위치: > 최신 기사 목록> Array_Diff ()에서 어려움을 겪는 이유는 무엇입니까? 이러한 문제를 해결하기위한 더 나은 대안은 무엇입니까?

Array_Diff ()에서 어려움을 겪는 이유는 무엇입니까? 이러한 문제를 해결하기위한 더 나은 대안은 무엇입니까?

M66 2025-06-24

php에서 array_diff ()는 두 개 이상의 배열을 비교하고 첫 번째 배열에 나타나는 값을 반환하는 매우 일반적인 함수입니다. 이것은 1 차원 배열에 적합하지만 "넥 어레이"(즉, 배열의 요소가 여전히 배열 임)를 다루기 위해 사용하려고 할 때 생각만큼 간단하지 않다는 것을 알 수 있습니다.

Array_Diff ()는 어떻게 작동합니까?

Array_Diff () 의 공식 정의는 배열의 "값"을 비교하고 첫 번째 배열에는 존재하지만 다른 배열에는 존재하지 않는 "값"을 반환하는 것입니다. 간단한 1 차원 배열 예를 들어 보겠습니다.

 $a = ['apple', 'banana', 'cherry'];
$b = ['banana', 'dragonfruit'];

$result = array_diff($a, $b);
// 나오십시오 ['apple', 'cherry']

이것은 매우 간단합니다. 키에 관계없이 값을 비교합니다. 그러나 대신 중첩 어레이를 사용하면 결과가 다릅니다.

배열 중첩시 문제

다음 예를 살펴 보겠습니다.

 $a = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob']
];

$b = [
    ['id' => 2, 'name' => 'Bob']
];

$result = array_diff($a, $b);

$ result가 [ 'id'=> 1, 'name'=> 'Alice' 만 반환 할 것으로 기대할 수 있지만 실제로 전체 $ a가 반환됩니다. PHP가 == 배열을 비교할 때 값을 비교하기 위해 == 를 사용하고 중첩 어레이의 비교 방법은 생각하는 것만 큼 "스마트"가 아니기 때문입니다.

Array_Diff ()가 배열에서 배열을 처리 할 때 내부 메커니즘은 재귀 적으로 처리되지 않지만 전체 서브 어레이를 "값"으로 취급하고 문자열 유형과 비교하려고합니다. 서브 어레이의 구조가 약간 일치하지 않으면 (예 : 다른 키 순서와 같은) 내용이 정확히 동일하더라도 다른 값으로 간주됩니다.

더 나은 대안

1. 재귀 차이 세트 기능을 사용자 정의합니다

중첩 어레이를 올바르게 비교하려면 배열 항목의 내용을 항목별로 비교하기 위해 사용자 정의 기능을 작성할 수 있습니다.

 function array_diff_recursive($a, $b) {
    $diff = [];

    foreach ($a as $itemA) {
        $found = false;
        foreach ($b as $itemB) {
            if ($itemA == $itemB) {
                $found = true;
                break;
            }
        }
        if (!$found) {
            $diff[] = $itemA;
        }
    }

    return $diff;
}

$a = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob']
];

$b = [
    ['id' => 2, 'name' => 'Bob']
];

$result = array_diff_recursive($a, $b);
// 반품 [['id' => 1, 'name' => 'Alice']]

2. Array_udiff () 및 사용자 정의 비교 함수를 사용하십시오

Array_udiff ()는 복잡한 구조를 비교할 때 특히 유용한 사용자 정의 비교 함수를 제공 할 수 있습니다.

 function compare_nested_array($a, $b) {
    return $a == $b ? 0 : 1;
}

$result = array_udiff($a, $b, 'compare_nested_array');

이 메소드를 사용하면 이름이 동일한 지 여부에 관계없이 ID 필드가 일치하는지 여부에 대해서만 신경 쓰는 등 비교 로직을 사용자 정의 할 수 있습니다.

3. 해시 값 사용 (큰 배열에 적합)

많은 양의 데이터를 처리하면 각 서브 어레이에 대한 해시를 생성 한 다음 해시와 비교할 수도 있습니다.

 function get_hash($array) {
    return md5(json_encode($array));
}

$a_hashed = array_map('get_hash', $a);
$b_hashed = array_map('get_hash', $b);

$diff_keys = array_diff($a_hashed, $b_hashed);

$result = [];
foreach ($diff_keys as $key => $hash) {
    $result[] = $a[$key];
}

이 기술은 데이터 볼륨이 큰 시나리오에 적합합니다. 성능이 우수 할뿐만 아니라 복잡한 구조를 처리 할 수 ​​있습니다.

응용 프로그램 시나리오의 예

예를 들어 두 사용자 권한 목록 간의 차이점을 비교하는 인터페이스 서비스를 개발하고 있습니다.

 $oldPermissions = [
    ['module' => 'user', 'access' => 'read'],
    ['module' => 'admin', 'access' => 'write'],
];

$newPermissions = [
    ['module' => 'user', 'access' => 'read'],
];

$removed = array_diff_recursive($oldPermissions, $newPermissions);
// 권한 변경 사항을 상기시키기 위해 관리자에게 이메일을 보낼 수 있습니다.

또는 구성 버전 차이를 처리 할 때이 메소드를 사용하여 구성 항목이 추가되었는지 또는 삭제되었는지 여부를 결정할 수도 있습니다.

결론

Array_diff ()는 간단한 배열을 다룰 때 매우 강력하지만 일단 중첩 구조에 들어가면 부도덕 한 것 같습니다. 다행히도 PHP는 강력한 도구 (예 : Array_udiff () , 사용자 정의 기능)를 제공하며 특정 요구에 유연하게 대응할 수도 있습니다.

좋은 배열 비교 로직을 작성하면 데이터 오류를 피할 수있을뿐만 아니라 시스템을보다 안정적으로 만들 수 있습니다. 실제 프로젝트에서 이러한 기술을 사용하여 코드를보다 강력하게 만들 수 있기를 바랍니다.