IT

개체를 포함하는 두 어레이를 병합하고 중복된 값을 제거합니다.

itgroup 2023. 1. 12. 22:12
반응형

개체를 포함하는 두 어레이를 병합하고 중복된 값을 제거합니다.

두 개의 객체 어레이를 하나의 어레이로 병합하고 중복된 개체를 제거해야 합니다.email가치.

내가 어떻게 그럴 수 있을까?

샘플 어레이는 다음과 같습니다.

$array1 = [
    (object) ["email" => "gffggfg"],
    (object) ["email" => "wefwef@test.it"],
    (object) ["email" => "wefewf"],
];
$array2 = [
    (object) ["email" => "gffggfg@test.it"],
    (object) ["email" => "wefwef"],
    (object) ["email" => "wefewf"],
];

예상 결과는 다음과 같습니다.

[
   (object) ['email' => 'gffggfg'],
   (object) ['email' => 'wefwef@test.it'],
   (object) ['email' => 'wefewf'],
   (object) ['email' => 'gffggfg@test.it'],
   (object) ['email' => 'wefwef'],
]

기능과 기능을 조합할 수 있습니다(두 제목 모두 매우 알기 쉬움).

$array = array_unique (array_merge ($array1, $array2));

질문을 올바르게 이해한 경우:

 $a1 = Array(1,2,3,4);
 $a2 = Array(4,5,6,7);
 $array =  array_diff(array_merge($a1,$a2),array_intersect($a1,$a2));
 print_r($array);

돌아가다

Array
(
[0] => 1
[1] => 2
[2] => 3
[5] => 5
[6] => 6
[7] => 7
)

제가 상상할 수 있는 모든 방법을 벤치마킹하고 있습니다.10~20개의 문자열 요소를 여러 어레이로 쌓는 테스트를 실시하여 하나의 어레이에 모든 고유 문자열을 포함시켰습니다.이는 2개의 어레이를 스태킹하는 경우와 거의 동일합니다.

내가 찾은 가장 빠른 것이 내가 시도한 가장 간단한 것이다.

$uniques = [];
foreach($manyArrays as $arr ) {
  $uniques = array_unique(array_merge($uniques, $arr));
}

반복할 때마다 유니크 배열을 정렬해야 하기 때문에 나는 이것을 '너무 순진해서 작동하지 않는다'고 낙인찍었다.그러나 이는 다른 어떤 방법보다 빠릅니다.manyArrays에서 500.000개의 요소를 사용하여 테스트합니다.각 요소에는 PHP 7.3의 10~20개의 문자열이 포함되어 있습니다.

근소한 차이로 두 번째가 이 방법으로, 약 10% 느립니다.

$uniques = [];
foreach($manyArrays as $arr ) {
  foreach($arr as $v) {
    if( !in_array($v, $uniques, false) ) {
      $uniques[] = $v;
    }
  }
}

두 번째 방법은 엄격한 유형 확인을 위해 in_array()의 'strict' 매개 변수를 지원하므로 경우에 따라 더 나을 수 있습니다.true로 설정하면 두 번째 옵션은 첫 번째 옵션(약 40%)보다 상당히 느려집니다.첫 번째 옵션은 엄격한 유형 확인을 지원하지 않습니다.

신속한 솔루션:

function concatArrays($arrays){
    $buf = [];
    foreach($arrays as $arr){
        foreach($arr as $v){
            $buf[$v] = true;
        }
    }
    return array_keys($buf);
}


$array = concatArrays([$array1, $array2]);

왜냐하면email오브젝트 배열의 속성에 중복되지 않는 값이 포함되어 있기 때문에 일시적으로 첫 번째 레벨 키를 할당할 수 있습니다.array_column()그런 다음 두 배열을 유니언 연산자와 병합합니다(함수 없는 작업).

임시 키가 다음 프로세스를 중단하는 경우 어레이를 다시 인덱싱할 수 있습니다.array_values().

코드: (데모)

var_export(
    array_values(
        array_column($array1, null, 'email')
        + array_column($array2, null, 'email')
    )
);

출력:

array (
  0 => 
  (object) array(
     'email' => 'gffggfg',
  ),
  1 => 
  (object) array(
     'email' => 'wefwef@test.it',
  ),
  2 => 
  (object) array(
     'email' => 'wefewf',
  ),
  3 => 
  (object) array(
     'email' => 'gffggfg@test.it',
  ),
  4 => 
  (object) array(
     'email' => 'wefwef',
  ),
)

"Merge and keep unique objects"는 또한 특별한 깃발과 함께 작동합니다.

코드: (데모)

var_export(
    array_unique(
        array_merge($array1, $array2),
        SORT_REGULAR
    )
);
// same result as other snippet

아주 오래된 실이긴 하지만...OP의 배열에 개체가 포함되어 있습니다.만약 내가 op이라면, 나는 이메일을 반환하는 __toString() 함수와 함께 컨스트럭터의 서브 어레이를 수신하는 클래스를 선언할 것이다.op이 오브젝트를 해당 클래스의 인스턴스로 만든 경우 array_unique는 비교 시 __toString()을 호출해야 합니다.

조금 늦은 답변이지만, 방금 찾은 바로는 어레이 유니온 오퍼레이터가+(여기서 3번째 섹션에 있습니다)는, 그 작업을 꽤 큰폭으로 실시합니다.

$array1 + $array2 = $array //if duplicate found, the value in $array1 will be considered ($array2 value for array_merge, if keys clearly specified)

언급URL : https://stackoverflow.com/questions/10572546/merge-two-arrays-containing-objects-and-remove-duplicate-values

반응형