문제

내가 배열

Array(
[0] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[1] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[2] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 8
        [frame_id] => 8
    )

[3] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

[4] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )

)

당신이 볼 수있는 키에는 0 이와 같은 1,3 및 4.키 2 은 다릅니다.

실행하는 경우 array_unique 기능에서 그들만 남았

Array (
[0] => Array
    (
        [0] => 33
        [user_id] => 33
        [1] => 3
        [frame_id] => 3
    )
)

어떤 아이디어를 왜 array_unique 없이 예상대로 작동하고 있습니까?

도움이 되었습니까?

해결책

It's because array_unique compares items using a string comparison. From the docs:

Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.

The string representation of an array is simply the word Array, no matter what its contents are.

You can do what you want to do by using the following:

$arr = array(
    array('user_id' => 33, 'frame_id' => 3),
    array('user_id' => 33, 'frame_id' => 3),
    array('user_id' => 33, 'frame_id' => 8)
);

$arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));

//result:
array
  0 => 
    array
      'user_id' => int 33
      'user' => int 3
  2 => 
    array
      'user_id' => int 33
      'user' => int 8

Here's how it works:

  1. Each array item is serialized. This will be unique based on the array's contents.

  2. The results of this are run through array_unique, so only arrays with unique signatures are left.

  3. array_intersect_key will take the keys of the unique items from the map/unique function (since the source array's keys are preserved) and pull them out of your original source array.

다른 팁

array_unique() only supports multi-dimensional arrays in PHP 5.2.9 and higher.

Instead, you can create a hash of the array and check it for unique-ness.

$hashes = array(); 

foreach($array as $val) { 
    $hashes[md5(serialize($val))] = $val; 
} 

array_unique($hashes);

Here's an improved version of @ryeguy's answer:

<?php

$arr = array(
    array('user_id' => 33, 'tmp_id' => 3),
    array('user_id' => 33, 'tmp_id' => 4),
    array('user_id' => 33, 'tmp_id' => 5)
);


# $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
$arr = array_intersect_key($arr, array_unique(array_map(function ($el) {
    return $el['user_id'];
}, $arr)));

//result:
array
  0 => 
    array
      'user_id' => int 33
      'tmp_id' => int 3

First, it doesn't do unneeded serialization. Second, sometimes attributes may be different even so id is the same.

I've run into it with Google Places API. I was combining results of several requests with different type of objects (think tags). But I got duplicates, since an object may be put into several categories (types). And the method with serialize didn't work, since the attrs were different, namely, photo_reference and reference. Probably these are like temporary ids.

array_unique deosn't work recursive, so it just thinks "this are all Arrays, let's kill all but one... here we go!"

빠른 답변(TL;박사)

  • 고유한 값을 추출할 수 있 PHP 의 배열 AssociativeArrays 를 사용하여 foreach
  • 이것은 단순한 접근 방식

자세한 응답

컨텍스트

  • PHP5.3
  • PHP 의 배열 AssociativeArrays(tabluar 합성 데이터 변수)
  • 의 대체 이름을 이 복합변수가 ArrayOfDictionary(AOD)

문제

  • 시나리오: DeveloperMarsher 는 PHP 테이블 형식의 복합변수
    • DeveloperMarsher 소원을 추출하는 고유한 값에 특정 이름 값 쌍
    • 아래 예에서,DeveloperMarsher 을 얻을하고자하는 행에 대한 각별 fname 이름 값 쌍

솔루션

  • example01;;DeveloperMarsher 으로 시작 tabluar 데이터 변수에는 다음과 같습니다

    $aodtable = json_decode('[
    {
      "fname": "homer"
      ,"lname": "simpson"
    },
    {
      "fname": "homer"
      ,"lname": "jackson"
    },
    {
      "fname": "homer"
      ,"lname": "johnson"
    },
    {
      "fname": "bart"
      ,"lname": "johnson"
    },
    {
      "fname": "bart"
      ,"lname": "jackson"
    },
    {
      "fname": "bart"
      ,"lname": "simpson"
    },
    {
      "fname": "fred"
      ,"lname": "flintstone"
    }
    ]',true);
    
  • example01;;DeveloperMarsher 추출 할 수 있습니다 고유한 값으로 foreach 루프는 트랙이 보 값

    $sgfield  =   'fname';
    $bgnocase =   true;
    
    //
    $targfield  =   $sgfield;
    $ddseen     =   Array();
    $vout       =   Array();
    foreach ($aodtable as $datarow) {
    if( (boolean) $bgnocase == true ){ @$datarow[$targfield] = @strtolower($datarow[$targfield]); }
    if( (string) @$ddseen[ $datarow[$targfield] ] == '' ){
      $rowout   = array_intersect_key($datarow, array_flip(array_keys($datarow)));
      $ddseen[ $datarow[$targfield] ] = $datarow[$targfield];
      $vout[] = Array( $rowout );
    }
    }
    //;;
    
    print var_export( $vout, true );
    

출력 결과

array (
  0 =>
  array (
    0 =>
    array (
      'fname' => 'homer',
      'lname' => 'simpson',
    ),
  ),
  1 =>
  array (
    0 =>
    array (
      'fname' => 'bart',
      'lname' => 'johnson',
    ),
  ),
  2 =>
  array (
    0 =>
    array (
      'fname' => 'fred',
      'lname' => 'flintstone',
    ),
  ),
)

  • 이 솔루션은 집계하지는 않에 있는 필드의 독특한 작업
  • 임의로 이름 값 쌍으로부터 반환되는 임의로 선택한 뚜렷한 행
  • 임의의 정렬 순서 출력
  • 임의로 취급의 편지-케이스(은 자본에서 뚜렷한 낮은 경우?)

또한 참조

  • php array_intersect_key
  • php array_flip
function array_unique_recursive($array)
{
    $array = array_unique($array, SORT_REGULAR);

    foreach ($array as $key => $elem) {
        if (is_array($elem)) {
            $array[$key] = array_unique_recursive($elem);
        }
    }

    return $array;
}

Doesn't that do the trick ?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top