답변:
다른 방법이 있습니다. 중간 변수는 저장되지 않습니다.
이를 사용하여 다양한 중첩 쿼리의 결과를 중복 제거했습니다.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
serialize(array('a' => '1', 'b' => '1'))
와 다른 것을주의하십시오 serialize(array('b' => '1', 'a' => '1'))
. 이 옵션은 sets
또는로 사용되는 배열에 실패합니다 (hash)maps
.
5.2.9부터 다음 과 같이 플래그 array_unique()
를 사용하면 사용할 수 있습니다 SORT_REGULAR
.
array_unique($array, SORT_REGULAR);
이를 통해 함수 $a == $b
가 사용중인 것처럼 요소를 동등하게 비교할 수 있으며 , 이는 귀하의 경우에 완벽합니다.
산출
Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
)
그러나 설명서 에는 다음 사항이 명시되어 있습니다.
array_unique()
다차원 배열에서는 작동하지 않습니다.
비슷한 문제가 있었지만 100 % 작동하는 솔루션을 찾았습니다.
<?php
function super_unique($array,$key)
{
$temp_array = [];
foreach ($array as &$v) {
if (!isset($temp_array[$v[$key]]))
$temp_array[$v[$key]] =& $v;
}
$array = array_values($temp_array);
return $array;
}
$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";
echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));
?>
또 다른 방법. 키도 보존합니다.
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
array_unique () 문서 에 대한 사용자 의견에는 이에 대한 많은 솔루션이 있습니다. 다음 중 하나입니다.
rbnsn 닷컴에서 kenrbnsn
2005 년 9 월 27 일 12시 9 분다중 부담 배열을위한 또 다른 Array_Unique. 나는 이것을 2 차원 배열에서만 테스트했지만 더 일반화하거나 재귀를 사용하도록 만들 수 있습니다.
이 함수는 serialize, array_unique 및 unserialize 함수를 사용하여 작업을 수행합니다.
function multi_unique($array) { foreach ($array as $k=>$na) $new[$k] = serialize($na); $uniq = array_unique($new); foreach($uniq as $k=>$ser) $new1[$k] = unserialize($ser); return ($new1); }
http://ca3.php.net/manual/en/function.array-unique.php#57202 에서 가져온 것 입니다.
"중복 제거"가 "중복 제거, 그러나 복제"를 의미하는 경우 해결책은 array_unique(...)
"식별자 열"을 먼저 적용한 다음 열 배열에서 제거 된 모든 키를 원래 배열에서 제거하는 것입니다. :
$array = [
[
'id' => '123',
'foo' => 'aaa',
'bar' => 'bbb'
],
[
'id' => '123',
'foo' => 'ccc',
'bar' => 'ddd'
],
[
'id' => '567',
'foo' => 'eee',
'bar' => 'fff'
]
];
$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);
결과는 다음과 같습니다.
Array
(
[0] => Array
(
[id] => 123
[foo] => aaa
[bar] => bbb
)
[2] => Array
(
[id] => 567
[foo] => eee
[bar] => fff
)
)
Array
(
[0] => Array
(
[id] => 1
[name] => john
)
[1] => Array
(
[id] => 2
[name] => smith
)
[2] => Array
(
[id] => 3
[name] => john
)
[3] => Array
(
[id] => 4
[name] => robert
)
)
$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);
그러면 배열에서 중복 이름이 제거됩니다. 키로 독특한
$array
의 키가 "0"에서 시작 하는지 확인하십시오 . 이 가능 $array
경우의 키를 다른 번호로 시작 $array
종래 배열을 조작의 결과이다. array_values
키를 다시 "0"으로 재설정하는 데 사용
SORT_REGULAR 옵션을 두 번째 매개 변수로 사용하십시오.
$uniqueArray = array_unique($array, SORT_REGULAR);
다차원 배열을 고유하게하는 매우 쉽고 논리적 인 방법은 다음과 같습니다.
이와 같은 배열이있는 경우 :
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value1
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value4
)
)
foreach
이것을 해결하는 데 사용 하십시오 :
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
다음과 같은 결과가 나타납니다.
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
[4] => Value4
)
)
키 순서를 다시 정렬하려면
foreach($array as $k=>$v){
$unique= array_values(array_unique($v));
$array[$k]=$unique;
}
이 작업은 다음과 같이 정렬 된 키 값을 제공합니다.
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
[3] => Value4
)
)
이것이 모든 것을 지우기를 바랍니다.
다음과 같은 배열이있는 경우 :
(사용자는 배열의 이름입니다)
Array=>
[0] => (array)
'user' => 'john'
'age' => '23'
[1] => (array)
'user' => 'jane'
'age' => '20'
[2]=> (array)
'user' => 'john'
'age' => '23'
중복을 삭제하고 싶습니다 ...
$serialized = array();
for ($i=0; $i < sizeof($users); $i++) {
$test = in_array($users['user'], $serialized);
if ($test == false) {
$serialized[] = $users['user'];
}
}
해결책이 될 수 있습니다 : P
사람들이 말하는 array_unique()
속도가 매우 느리므로 여기에 한 수준의 다차원 배열에 사용하는 스 니펫이 있습니다.
$serialized_array = array_map("serialize", $input);
foreach ($serialized_array as $key => $val) {
$result[$val] = true;
}
$output = array_map("unserialize", (array_keys($result)));
$output = array_map('unserialize', array_keys($result));
많은 사람들이 고유 한 다차원 배열을 만드는 방법을 물었습니다. 나는 당신의 의견을 참조하여 도움이됩니다.
우선 솔루션을 제공하는 @jeromegamez @daveilers에게 감사드립니다. 그러나 내가 대답 할 때마다 그들은이 '직렬화'와 '직렬화 해제'가 어떻게 작동하는지 물었습니다. 그렇기 때문에 더 많은 사람들이이 개념을 이해하는 데 도움이되도록이 이유를 여러분과 공유하고 싶습니다.
왜 우리가 'serialize'와 'serialize'를 단계적으로 사용하는지 설명하고 있습니다.
1 단계 : 다차원 배열을 1 차원 배열로 변환
다차원 배열을 1 차원 배열로 변환하려면 먼저 배열 내부의 모든 요소 (중첩 배열 포함)의 바이트 스트림 표현을 생성하십시오. serialize () 함수는 값의 바이트 스트림 표현을 생성 할 수 있습니다. 모든 요소의 바이트 스트림 표현을 생성하려면 array_map () 함수 내에서 serialize () 함수를 콜백 함수로 호출하십시오. 결과는 다차원 배열의 레벨 수에 관계없이 1 차원 배열이됩니다.
2 단계 : 값을 고유하게 만들기
이 1 차원 배열을 고유하게 만들려면 array_unique () 함수를 사용하십시오.
3 단계 : 다차원 배열로 되돌리기
배열은 이제 고유하지만 값은 바이트 스트림 표현처럼 보입니다. 다시 다차원 배열로 되돌리려면 unserialize () 함수를 사용하십시오.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
이 모든 것에 다시 한번 감사드립니다.
직렬화하고 고유 한 대안
$test = [
['abc','def'],
['ghi','jkl'],
['mno','pql'],
['abc','def'],
['ghi','jkl'],
['mno','pql'],
];
$result = array_reduce(
$test,
function($carry,$item){
if(!in_array($item,$carry)) {
array_push($carry,$item);
}
return $carry;
},
[]
);
var_dump($result);
/*
php unique.php
array(3) {
[0] =>
array(2) {
[0] =>
string(3) "abc"
[1] =>
string(3) "def"
}
[1] =>
array(2) {
[0] =>
string(3) "ghi"
[1] =>
string(3) "jkl"
}
[2] =>
array(2) {
[0] =>
string(3) "mno"
[1] =>
string(3) "pql"
}
}
* /
이런 배열이 있다면
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => b
),
[3] => array
(
[subject] => d
[object] => c
),
[4] => array
(
[subject] => c
[object] => a
),
[5] => array
(
[subject] => c
[object] => d
)
)
그리고 당신은 다음과 같은 배열을 얻고 싶습니다 :
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => c
)
)
또는
data = array
(
[0] => array
(
[subject] => d
[object] => b
),
[1] => array
(
[subject] => c
[object] => a
),
[2] => array
(
[subject] => c
[object] => d
)
)
다음 코드가 도움이 될 수 있습니다
$data1 = array();
$data1 = $data;
for($q=0;$q<count($data);$q++)
{
for($p=0;$p<count($data1);$p++)
{
if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
{
$data1[$p]["subject"] = $data[$q]["subject"];
$data1[$p]["object"] = $data[$q]["object"];
}
}
}
$data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
$data = $data1;
이 문제에 대해 많은 생각을했으며 최적의 솔루션이 두 가지 규칙을 따라야한다고 결정했습니다.
그것을 염두에두고 PHP의 모든 단점을 감안할 때, 내가 생각해 낸 해결책은 다음과 같습니다. 다른 답변과 달리 원하는 키를 기반으로 요소를 제거 할 수 있습니다. 입력 배열은 숫자 키일 것으로 예상됩니다.
$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
if (isset($input[$i])) {
for ($j = $i+1; $j < $count_array; $j++) {
if (isset($input[$j])) {
//this is where you do your comparison for dupes
if ($input[$i]['checksum'] == $input[$j]['checksum']) {
unset($input[$j]);
}
}
}
}
}
유일한 단점은 반복이 완료 될 때 키가 순서대로 정렬되지 않는다는 것입니다. 이후에 foreach 루프 만 사용하는 경우에는 문제가되지 않지만 for 루프를 사용해야하는 $input = array_values($input);
경우 위 번호를 입력하여 키의 번호를 다시 지정할 수 있습니다 .