어떻게 사용하 array_unique 에서의 배열?
-
23-09-2019 - |
문제
내가 배열
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:
Each array item is serialized. This will be unique based on the array's contents.
The results of this are run through
array_unique
, so only arrays with unique signatures are left.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 Array
s, 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 ?