2014-04-10 5 views
1

PHP에서 다른 배열에없는 배열 하나를 찾으려고합니다. 나는 정의 된 콜백과 함께 array_udiff 함수를 사용해야한다는 인상하에있다.PHP array_udiff functionality

첫 번째 배열은 id 속성을 가진 객체의 배열입니다. 두 번째 배열은 name 속성을 가진 객체의 배열입니다. 이름 특성에는 이름을 구성하는 문자열 내에 ID 번호가 들어 있습니다.

제 목표는 첫 번째 배열의 각 개체 ID가 두 번째 배열의 이름에 ID가 포함 된 해당 개체가 있는지 확인하는 것입니다. 여기 내 코드는 다음과 같습니다

<?php 

class NameObj { 

    public $name; 

    function __construct($name){ 
     $this->name = $name; 
    } 
} 

class IdObj{ 

    public $id; 

    function __construct($id){ 
     $this->id = $id; 
    } 
} 

$idArray = array(
    new IdObj(1), 
    new IdObj(2), 
    new IdObj(3) 
); 

$nameArray = array(
    new NameObj('1 - Object 1 Name'), 
    new NameObj('2 - Object 2 Name') 
); 

function custom_diff($oId, $oName){ 
    $splitName = explode(' - ', $oName->name); 
    $idFromName = $splitName[0]; 

    $id = $oId->id; 

    if($idFromName == $id) return 0; 
    return $idFromName > $id ? 1 : -1; 
} 

$missing_objects = array_udiff($idArray, $nameArray, 'custom_diff'); 

print_r($missing_objects); 

?> 

내가 첫 번째 배열 만 세 번째 객체를 포함하는 배열을 보여야하는데, 대신 나는이 얻을 을 :

PHP Notice: Undefined property: IdObj::$name in /home/ubuntu/test2.php on line 33 
PHP Notice: Undefined property: IdObj::$name in /home/ubuntu/test2.php on line 33 
PHP Notice: Undefined property: NameObj::$id in /home/ubuntu/test2.php on line 36 
PHP Notice: Undefined property: IdObj::$name in /home/ubuntu/test2.php on line 33 
PHP Notice: Undefined property: IdObj::$name in /home/ubuntu/test2.php on line 33 
Array 
(
[1] => IdObj Object 
    (
     [id] => 2 
    ) 

[2] => IdObj Object 
    (
     [id] => 3 
    ) 

) 

내가 여기서 무엇을 놓치고? array_udiff 기능을 잘못 사용하고 있습니까?

답변

1

잘못 사용하고 있습니다. 특히, 첫 번째 배열의 항목과 두 번째 배열의 항목을이 순서로 인수로 항상 호출한다고 가정합니다. 그러나 PHP는 그러한 보장을하지 않습니다.

이제는 비교를 통해 해당 인수의 유형을 감지하고 그에 따라 작동 할 수 있지만, 현재의 경우와 비교해 볼 때 가장 좋은 아이디어는 아닙니다. array_udiff은 유사하게 구조화 된 배열에서 작동해야합니다. 또한 목표를 달성하기 위해 두 번째 요소의 각 요소에 대해 첫 번째 배열의 각 요소를 확인하지 않아도됩니다. 여기

내가 (코드의 비트를 차용) 그것을 할 것입니다 방법은 다음과 같습니다

$extractor = function($o) { return explode(' - ', $o->name)[0]; }; 
$idsFromNames = array_flip(array_map($extractor, $nameArray)); 

foreach ($idArray as $k => $o) { 
    if (!isset($idsFromNames[$o->id])) { 
     unset($idArray[$k]); 
    } 
} 
+0

정말 고마워요 존. 이것은 대단한 대답입니다. 전문성에 진심으로 감사드립니다. – flyingL123