PHP Conference Japan 2024

array_unique

(PHP 4 >= 4.0.1,PHP 5,PHP 7,PHP 8)

array_unique從陣列中移除重複的值

描述

array_unique(array $array, int $flags = SORT_STRING): array

接收輸入的 array,並傳回一個不含重複值的新陣列。

請注意,索引鍵會被保留。如果多個元素在給定的 flags 下比較相等,則將保留第一個相等元素的索引鍵和值。

注意 只有在 (string) $elem1 === (string) $elem2 時,才會將兩個元素視為相等,也就是當字串表示法相同時,會使用第一個元素。

參數

array

輸入的陣列。

flags

可選的第二個參數 flags 可用來使用這些值修改比較行為

比較類型標誌

傳回值

傳回篩選後的陣列。

變更日誌

版本 描述
7.2.0 如果 flagsSORT_STRING,先前 array 已複製並移除非唯一元素(之後不封裝陣列),但現在透過新增唯一元素來建構新的陣列。這可能會導致不同的數值索引。

範例

範例 1 array_unique() 範例

<?php
$input
= array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>

以上範例將會輸出

Array
(
    [a] => green
    [0] => red
    [1] => blue
)

範例 2 array_unique() 和類型

<?php
$input
= array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);
?>

以上範例將會輸出

array(2) {
  [0] => int(4)
  [2] => string(1) "3"
}

附註

注意 請注意,array_unique() 不適用於多維陣列。

參見

新增註解

使用者貢獻的註解 33 則註解

Ghanshyam Katriya(anshkatriya at gmail)
9 年前
為任何單一索引鍵建立多維陣列唯一值。
例如,我想為特定代碼建立多維唯一陣列

代碼
我的陣列是這樣子的,

<?php
$details
= array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"9876543210"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
2 => array("id"=>"1", "name"=>"Mathew", "num"=>"784581254"),
);
?>

您可以針對任何欄位(如 id、name 或 num)設為唯一。

我為此開發了此函式
<?php
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();

foreach(
$array as $val) {
if (!
in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return
$temp_array;
}
?>

現在,從您的程式碼中的任何位置呼叫此函式,

類似這樣,
<?php
$details
= unique_multidim_array($details,'id');
?>

輸出會像這樣
<?php
$details
= array(
0 => array("id"=>"1","name"=>"Mike","num"=>"9876543210"),
1 => array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),
);
?>
Mike D. - michal at euro-net.pl
1 年前
修改了 Ghanshyam Katriya (anshkatriya at gmail) 原先發布的程式碼 [此處最高票的評論]。

1. 在 php 7.4 中,計數器 $i 會導致函式中斷。已完全移除(我認為這本來就是浪費鍵盤敲擊)。
2. 我加入了第二個回傳值 - 重複項的陣列。所以你可以取得兩者並比較它們(我必須這樣做)。

範例陣列(從原始貼文複製貼上)
<?php
$details
= array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"9876543210"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
2 => array("id"=>"1", "name"=>"Mathew", "num"=>"784581254"),
);
?>

函式
<?php
function unique_multidim_array($array, $key) : array {
$uniq_array = array();
$dup_array = array();
$key_array = array();

foreach(
$array as $val) {
if (!
in_array($val[$key], $key_array)) {
$key_array[] = $val[$key];
$uniq_array[] = $val;
/*
# 第一個要檢查的清單:
# echo "ID 或其他: " . $val['building_id'] . "; 其他: " . $val['nodes_name'] . (...) "\n";
*/
} else {
$dup_array[] = $val;
/*
# 第二個要檢查的清單:
# echo "ID 或其他: " . $val['building_id'] . "; 其他: " . $val['nodes_name'] . (...) "\n";
*/
}
}
return array(
$uniq_array, $dup_array, /* $key_array */);
}
?>

用法
<?php
list($unique_addresses, $duplicates, /* $unique_keys */) = unique_multidim_array($details,'id');
?>

接著
var_dump($unique_addresses);

var_dump($duplicates);
或 foreach 或任何其他方式。我個人只是在函式本身 echo 輸出第一個和第二個(兩個都加上雙重註解)清單(然後將兩者複製到 notepad++ 並比較它們 - 只是為了 100% 確定),但如果你想用它做其他事情 - 請盡情享用 :)
此外 - 作為額外的好處 - 你還可以獲得一個你搜尋的 UNIQUE 鍵的陣列(只需取消註解函式回傳值和函式呼叫程式碼中的 >$key_array<)。

從範例陣列程式碼回傳
var_dump($unique_addresses);
array(2) {
[0]=>
array(3) {
["id"]=>
string(1) "1"
["name"]=>
string(4) "Mike"
["num"]=>
string(10) "9876543210"
}
[1]=>
array(3) {
["id"]=>
string(1) "2"
["name"]=>
string(7) "Carissa"
["num"]=>
string(11) "08548596258"
}
}

var_dump($duplicates);
array(1) {
[0]=>
array(3) {
["id"]=>
string(1) "1"
["name"]=>
string(6) "Mathew"
["num"]=>
string(9) "784581254"
}
}

加上鍵,如果你需要的話。

附註:在我實際的資料庫查詢案例中,我得到了大約 4 千個唯一值和 1.5 萬個重複值 :)
falundir at gmail dot com
6 年前
我覺得很奇怪,這個函式竟然沒有一個版本允許你使用比較器可呼叫物件來判斷項目是否相等(就像 array_udiff 和 array_uintersect 一樣)。所以,這是我的版本給你

<?php
function array_uunique(array $array, callable $comparator): array {
$unique_array = [];
do {
$element = array_shift($array);
$unique_array[] = $element;

$array = array_udiff(
$array,
[
$element],
$comparator
);
} while (
count($array) > 0);

return
$unique_array;
}
?>

這是測試程式碼

<?php
class Foo {

public
$a;

public function
__construct(int $a) {
$this->a = $a;
}
}

$array_of_objects = [new Foo(2), new Foo(1), new Foo(3), new Foo(2), new Foo(2), new Foo(1)];

$comparator = function (Foo $foo1, Foo $foo2): int {
return
$foo1->a <=> $foo2->a;
};

var_dump(array_uunique($array_of_objects, $comparator)); // 應該輸出 [Foo(2), Foo(1), Foo(3)]
?>
Anonymous
14 年前
使用 foreach 和 array_keys 通常比 array_unique 快

<?php

$max
= 1000000;
$arr = range(1,$max,3);
$arr2 = range(1,$max,2);
$arr = array_merge($arr,$arr2);

$time = -microtime(true);
$res1 = array_unique($arr);
$time += microtime(true);
echo
"去重後為 ".count($res1).",耗時 ".$time;
// 去重後為 666667,耗時 32.300781965256

$time = -microtime(true);
$res2 = array();
foreach(
$arr as $key=>$val) {
$res2[$val] = true;
}
$res2 = array_keys($res2);
$time += microtime(true);
echo
"<br />去重後為 ".count($res2).",耗時 ".$time;
// 去重後為 666667,耗時 0.84372591972351

?>
stoff@
7 年前
回覆關於 array_unique 與 foreach 效能測試。

在 PHP7 中,對 Packed 和 Immutable 陣列進行了重大變更,導致效能差異大幅降低。以下是在 php7.1 上相同的測試:
http://sandbox.onlinephpfunctions.com/code/2a9e986690ef8505490489581c1c0e70f20d26d1

$max = 770000; //記憶體配置中足夠大的數字
$arr = range(1,$max,3);
$arr2 = range(1,$max,2);
$arr = array_merge($arr,$arr2);

$time = -microtime(true);
$res1 = array_unique($arr);
$time += microtime(true);
echo "去重後為 ".count($res1).",耗時 ".$time;
// 去重後為 513333,耗時 1.0876770019531

$time = -microtime(true);
$res2 = array();
foreach($arr as $key=>$val) {
$res2[$val] = true;
}
$res2 = array_keys($res2);
$time += microtime(true);
echo "<br />去重後為 ".count($res2).",耗時 ".$time;
// 去重後為 513333,耗時 0.054931879043579
calexandrepcjr at gmail dot com
7 年前
遵循 Ghanshyam Katriya 的想法,但使用物件陣列,其中 $key 與你想篩選陣列唯一性的物件屬性相關

<?php
function obj_multi_unique($obj, $key = false)
{
$totalObjs = count($obj);
if (
is_array($obj) && $totalObjs > 0 && is_object($obj[0]) && ($key && !is_numeric($key))) {
for (
$i = 0; $i < $totalObjs; $i++) {
if (isset(
$obj[$i])) {
for (
$j = $i + 1; $j < $totalObjs; $j++) {
if (isset(
$obj[$j]) && $obj[$i]->{$key} === $obj[$j]->{$key}) {
unset(
$obj[$j]);
}
}
}
}
return
array_values($obj);
} else {
throw new
Exception('Invalid argument or your array of objects is empty');
}
}
?>
Ray dot Paseur at SometimesUsesGmail dot com
16 年前
我需要找出資料表中重複的電子郵件地址,所以我寫了 array_not_unique() 函式

<?php

function array_not_unique($raw_array) {
$dupes = array();
natcasesort($raw_array);
reset ($raw_array);

$old_key = NULL;
$old_value = NULL;
foreach (
$raw_array as $key => $value) {
if (
$value === NULL) { continue; }
if (
$old_value == $value) {
$dupes[$old_key] = $old_value;
$dupes[$key] = $value;
}
$old_value = $value;
$old_key = $key;
}
return
$dupes;
}

$raw_array = array();
$raw_array[1] = 'abc@xyz.com';
$raw_array[2] = 'def@xyz.com';
$raw_array[3] = 'ghi@xyz.com';
$raw_array[4] = 'abc@xyz.com'; // 重複

$common_stuff = array_not_unique($raw_array);
var_dump($common_stuff);
?>
free dot smilesrg at gmail dot com
2 年前
$a = new StdClass();
$b = new StdClass();

var_dump(array_unique([$a, $b, $b, $a], SORT_REGULAR));
//array(1) {
// [0]=>
// object(stdClass)#1 (0) {
// }
//}

$a->name = 'One';
$b->name = 'Two';

var_dump(array_unique([$a, $b, $b, $a], SORT_REGULAR));

//array(2) {
// [0]=>
// object(stdClass)#1 (1) {
// ["name"]=>
// string(3) "One"
// }
// [1]=>
// object(stdClass)#2 (1) {
// ["name"]=>
// string(3) "Two"
// }
//}
contact at evoweb dot fr
3 年前
這裡有一個解決方案,可以為帶有鍵的陣列產生唯一值並保留空值

<?php
function array_unique_kempty($array) {
$values = array_unique($array);
$return = array_combine(array_keys($array), array_fill(0,count($array),null));
return
array_merge($return,$values);
}

$myArray = [
"test1" => "aaa",
"test2" => null,
"test3" => "aaa",
"test4" => "bbb",
"test5" => null,
"test6" => "ccc",
"test7" => "ddd",
"test8" => "ccc"
];

echo
"<pre>".print_r(array_unique_kempty($myArray),true)."</pre>";

/*
Array
(
[test1] => aaa
[test2] =>
[test3] =>
[test4] => bbb
[test5] =>
[test6] => ccc
[test7] => ddd
[test8] =>
)
*/
?>
mnbayazit
17 年前
不區分大小寫;將保留第一個遇到的值。

<?php

function array_iunique($array) {
$lowered = array_map('strtolower', $array);
return
array_intersect_key($array, array_unique($lowered));
}

?>
PHP Expert
16 年前
PHP v4.x 及更高版本不區分大小寫。

<?php

function in_iarray($str, $a) {
foreach (
$a as $v) {
if (
strcasecmp($str, $v) == 0) {
return
true;
}
}
return
false;
}

function
array_iunique($a) {
$n = array();
foreach (
$a as $k => $v) {
if (!
in_iarray($v, $n)) {
$n[$k]=$v;
}
}
return
$n;
}

$input = array("aAa","bBb","cCc","AaA","ccC","ccc","CCC","bBB","AAA","XXX");
$result = array_iunique($input);
print_r($result);

/*
Array
(
[0] => aAa
[1] => bBb
[2] => cCc
[9] => XXX
)
*/
?>
sashasimkin at gmail dot com
12 年前
我的物件唯一函式

<?php
function object_unique( $obj ){
$objArray = (array) $obj;

$objArray = array_intersect_assoc( array_unique( $objArray ), $objArray );

foreach(
$obj as $n => $f ) {
if( !
array_key_exists( $n, $objArray ) ) unset( $obj->$n );
}

return
$obj;
}
?>

這段程式碼

<?php
class Test{
public
$pr0 = 'string';
public
$pr1 = 'string1';
public
$pr2 = 'string';
public
$pr3 = 'string2';
}

$obj = new Test;

var_dump( object_unique( $obj ) );
?>

會回傳
object(Test)[1]
public 'pr0' => string 'string' (length=6)
public 'pr1' => string 'string1' (length=7)
public 'pr3' => string 'string2' (length=7)
Victoire Nkolo at crinastudio.com
1 年前
<?php

//根據給定的屬性,從陣列中移除重複的物件

class ArrayFilter
{

public static function
dedupe_array_of_objets(array $array, string $property) : array
{
$i = 0;
$filteredArray = array();
$keyArray = array();

foreach(
$array as $item) {
if (!
in_array($item->$property, $keyArray)) {
$keyArray[$i] = $item->$property;
$filteredArray[$i] = $item;
}
$i++;
}
return
$filteredArray;
}
}
mostafatalebi at rocketmail dot com
10 年前
如果您需要取得已排序且不保留鍵值的陣列,請使用這段程式碼,它對我來說很有效

<?php

$array
= array("hello", "fine", "good", "fine", "hello", "bye");

$get_sorted_unique_array = array_values(array_unique($array));

?>

上面的程式碼會回傳一個既不重複又從零開始排序的陣列。
Dorphalsig
16 年前
我曾遇到 array_unique 處理多維陣列的問題... 也許有更好的方法可以做到,但這個方法適用於任何維度的陣列。

<?php
function arrayUnique($myArray)
{
if(!
is_array($myArray))
return
$myArray;

foreach (
$myArray as &$myvalue){
$myvalue=serialize($myvalue);
}

$myArray=array_unique($myArray);

foreach (
$myArray as &$myvalue){
$myvalue=unserialize($myvalue);
}

return
$myArray;

}
?>
regeda at inbox dot ru
14 年前
多維陣列的遞迴不重複處理

<?php
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));

foreach (
$result as $key => $value)
{
if (
is_array($value) )
{
$result[$key] = super_unique($value);
}
}

return
$result;
}
?>
agarcia at rsn dot com dot co
18 年前
這是一個處理多維陣列的腳本

<?php
function remove_dup($matriz) {
$aux_ini=array();
$entrega=array();
for(
$n=0;$n<count($matriz);$n++)
{
$aux_ini[]=serialize($matriz[$n]);
}
$mat=array_unique($aux_ini);
for(
$n=0;$n<count($matriz);$n++)
{

$entrega[]=unserialize($mat[$n]);

}
return
$entrega;
}
?>
keneks at gmail dot com
18 年前
利用 array_unique 的優勢,這裡有一個簡單的函數可以檢查陣列是否具有重複的值。

它只是比較原始陣列和經過 array_unique 處理的陣列之間的元素數量。

<?php

function array_has_duplicates(array $array)
{
$uniq = array_unique($array);
return
count($uniq) != count($array);
}

?>
quecoder at gmail
16 年前
另一種取得不重複值的方法是

<?php
$alpha
=array('a','b','c','a','b','d','e','f','f');

$alpha= array_keys(array_count_values($alpha));

print_r($alpha);
?>

輸出結果
Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f )
jusvalceanu - SPAM at SPAM - yahoo dot com
16 年前
所以...我的問題是多維排序。

<?php
$new
= array();
$exclude = array("");
for (
$i = 0; $i<=count($attribs)-1; $i++) {
if (!
in_array(trim($attribs[$i]["price"]) ,$exclude)) { $new[] = $attribs[$i]; $exclude[] = trim($attribs[$i]["price"]); }
}

?>

陣列 $attribs 是一個包含陣列的陣列。 $attrib 陣列中的每個陣列都由多個欄位組成(例如:name、length、price 等)。為了更容易理解,可以想像 $attrib 是由訪問者在您的線上購物網站上執行 SQL 查詢後產生的陣列...(所以... $attrib 中的每個陣列都是一個產品 :P)如果您只想排序不重複的結果,請使用以上方法或使用這個方法

<?php

/* 我們的產品陣列 */
$attribs[] = array(
"name" => "測試產品 1",
"length" => "42 公分",
"weight" => "0,5 公斤",
"price" => "10 美元",
"stock" => "100",
);

$attribs[] = array(
"name" => "測試產品 2",
"length" => "42 公分",
"weight" => "1,5 公斤",
"price" => "10 美元",
"stock" => "200",
);

/* 好東西 */

$new = array();
$exclude = array("");
for (
$i = 0; $i<=count($attribs)-1; $i++) {
if (!
in_array(trim($attribs[$i]["price"]) ,$exclude)) { $new[] = $attribs[$i]; $exclude[] = trim($attribs[$i]["price"]); }
}

print_r($new); // $new 是我們排序過的陣列

?>

盡情調整這個吧 ;)) 我知道你會的 ;))

來自羅馬尼亞的愛
網頁管理員 at jukkis dot net
17 年前
另一種「唯一欄位」化陣列的方法,在這種情況下是指物件的陣列
將想要的唯一欄位值保存在 array_filter 的回呼函數內的靜態陣列中。

範例
<?php
/* 範例物件 */
class myObj {
public
$id;
public
$value;
function
__construct( $id, $value ) {
$this->id = $id;
$this->value = $value;
}
}

/* 回呼函數 */
function uniquecol( $obj ) {
static
$idlist = array();

if (
in_array( $obj->id, $idlist ) )
return
false;

$idlist[] = $obj->id;
return
true;
}

/* 幾個陣列,第二個陣列中的元素與第一個陣列具有相同的 id */
$list = array( new myObj( 1, 1 ), new myObj( 2, 100 ) );
$list2 = array( new myObj( 1, 10 ), new myObj( 3, 100 ) );
$list3 = array_merge( $list, $list2 );

$unique = array_filter( $list3, 'uniquecol' );
print_r( $list3 );
print_r( $unique );

?>

此外,使用 array_merge( $unique ) 來重新索引。
Fabiano
6 年前
對於 PHP 7.1.12,這是 array_keys(array_flip())、array_flip(array_flip()),對於每次消除以及 array_unique 之間的比較。array_keys(array_flip()) 是從單維陣列中刪除重複值的最快方法

<?php

$max
= 1000000;
$arr = range(1,$max,3);
$arr2 = range(1,$max,2);
$arr = array_merge($arr,$arr2);

$time = -microtime(true);
$res1 = array_unique($arr);
$time += microtime(true);

echo
"<br>去重後為 ".count($res1)." 在 ".$time;
// 去重後為 666667 在 0.78185796737671
// 使用的記憶體:33558528

$time = -microtime(true);
$res2 = array_flip(array_flip($arr));
$time += microtime(true);

echo
"<br><br>去重後為 ".count($res2)." 在 ".$time;
// 去重後為 666667 在 0.072191953659058
// 使用的記憶體:3774873

$time = -microtime(true);
$res3 = array();
foreach(
$arr as $key=>$val) {
$res3[$val] = true;
}
$res3 = array_keys($res3);
$time += microtime(true);

echo
"<br /><br>去重後為 ".count($res3)." 在 ".$time;
// 去重後為 666667 在 0.095494985580444
// 使用的記憶體:33558528

$time = -microtime(true);
$res4 = array_keys(array_flip($arr));
$time += microtime(true);

echo
"<br /><br>去重後為 ".count($res4)." 在 ".$time;
// 去重後為 666667 在 0.05807900428772
// 使用的記憶體:33558528
zoolyka at gmail dot com
8 年前
我發現了以下「唯一化」多維陣列的最簡單方法

<?php

$array
= array(
'a' => array(1, 2),
'b' => array(1, 2),
'c' => array(2, 2),
'd' => array(2, 1),
'e' => array(1, 1),
);

$array = array_map('json_encode', $array);
$array = array_unique($array);
$array = array_map('json_decode', $array);

print_r($array);

?>

如您所見,「b」將在沒有任何錯誤或通知的情況下被移除。
subhrajyoti dot de007 at gmail dot com
6 年前
從多維陣列中移除重複項目的簡單且乾淨的方法。

<?php
$multi_array
= $multi_array [0];
$multi_array = array_unique($multi_array);
print_r($multi_array);
?>
geuis dot teses at gmail dot com
18 年前
這是我能找到/創建的最短程式碼,可從陣列中移除所有重複項目,然後重新索引鍵。

<?php

// 水果、蔬菜和其他食物:
$var = array('apple','banana','carrot','cat','dog','egg','eggplant','fish');

$var = array_values(array_unique($var));
?>
amri [ at t] dhstudio dot eu
14 年前
我搜尋了如何只顯示陣列中去重複的元素,但失敗了。
這是我的解決方案

<?php
function arrayUniqueElements($array)
{
return
array_unique(array_diff_assoc($array1,array_unique($array1)));
};
?>

範例
<?php
$arr1
= array('foo', 'bar', 'xyzzy', '&', 'xyzzy',
'baz', 'bat', '|', 'xyzzy', 'plugh',
'xyzzy', 'foobar', '|', 'plonk', 'xyzzy',
'apples', '&', 'xyzzy', 'oranges', 'xyzzy',
'pears','foobar');

$result=arrayUniqueElements($arr1);
print_r($result);exit;
?>

輸出結果

陣列
(
[4] => xyzzy
[12] => |
[16] => &
[21] => foobar
)
Ludovico Grossi
9 年前
[編輯註記:請注意,這在陣列中具有非純量值時效果不佳。陣列的鍵本身不能是陣列,也不能是串流、資源等。翻轉陣列會導致鍵名變更]

您可以直接在 PHP 中執行超快速版本的 array_unique,甚至比評論中發布的其他解決方案更快!

與內建函數相比,速度快了 20 倍!(比評論中的解決方案快 2 倍)。

<?php
function superfast_array_unique($array) {
return
array_keys(array_flip($array));
}
?>

這對於小型和大型陣列都更快。
memandeemail at gmail dot com
18 年前
問題
我已載入一個包含資料庫結果的陣列
查詢。欄位為「FirstName」和「LastName」。

我想要找到一種方法來串連這兩個欄位
欄位,然後只傳回該陣列的唯一值。
例如,如果資料庫查詢傳回
三個記錄的實例,其中 FirstName 為 John
而 LastName 為 Smith,在兩個不同的欄位中,我將
想要建立一個新陣列,其中包含所有
原始欄位,但其中只出現一次 John Smith。
感謝:Colin Campbell

解決方案

<?php
/**
* 與 implode 函數相同,但會傳回鍵,因此
*
* <code>
* $_GET = array('id' => '4587','with' => 'key');
* ...
* echo shared::implode_with_key('&',$_GET,'='); // 結果:id=4587&with=key
* ...
* </code>
*
* @param string $glue 在鍵 => 值之間放置的內容
* @param array $pieces 值
* @param string $hifen 分隔鍵的陣列和值
* @return string
* @author memandeemail at gmail dot com
*/
function implode_with_key($glue = null, $pieces, $hifen = ',') {
$return = null;
foreach (
$pieces as $tk => $tv) $return .= $glue.$tk.$hifen.$tv;
return
substr($return,1);
}

/**
* 從值樹傳回唯一值
*
* @param array $array_tree
* @return array
* @author memandeemail at gmail dot com
*/
function array_unique_tree($array_tree) {
$will_return = array(); $vtemp = array();
foreach (
$array_tree as $tkey => $tvalue) $vtemp[$tkey] = implode_with_key('&',$tvalue,'=');
foreach (
array_keys(array_unique($vtemp)) as $tvalue) $will_return[$tvalue] = $array_tree[$tvalue];
return
$will_return;
}

$problem = array_fill(0,3,
array(
'FirstName' => 'John', 'LastName' => 'Smith')
);

$problem[] = array('FirstName' => 'Davi', 'LastName' => 'S. Mesquita');
$problem[] = array('FirstName' => 'John', 'LastName' => 'Tom');

print_r($problem);

print_r(array_unique_tree($problem));
?>
tasiot
2 年前
array_unique 與 php 8.1 列舉不相容,因為列舉尚未具有字串表示法(即使是字串類型的 BackedEnum…)。
您會收到錯誤訊息:「無法將 XXXX 類別的物件轉換為字串。」

因此我寫了這個函數,它會建立列舉的字串表示法,並使用陣列鍵來移除重複項。

<?php

function array_unique_81(array $values): array
{
$unique = [];
foreach (
$values as $value) {
if (
$value instanceof \UnitEnum) {
$key = 'e:' . \get_class($value) . ':' . $value->name;
} else {
$key = 's:' . (string)$value;
}
$unique[$key] = $value;
}
return
\array_values($unique);
}

?>
Sbastien
2 年前
由於 PHP 的比較方式,您永遠無法將 null 與其他假值區分開來。
請注意在混合型別陣列中,true 和 false 布林值的吸收特性。

<?php

$a
= [true, false, null, '', '0', '123', 0, 123];
foreach ([
'SORT_REGULAR', 'SORT_NUMERIC', 'SORT_STRING', 'SORT_LOCALE_STRING'] as $flag) {
$a_new = array_unique($a, constant($flag));
echo
"{$flag} ==> ";
var_dump($a_new);
}

/*

輸出:

SORT_REGULAR ==> array(2) {
[0]=> bool(true)
[1]=> bool(false)
}
SORT_NUMERIC ==> array(3) {
[0]=> bool(true)
[1]=> bool(false)
[5]=> string(3) "123"
}
SORT_STRING ==> array(4) {
[0]=> bool(true)
[1]=> bool(false)
[4]=> string(1) "0"
[5]=> string(3) "123"
}
SORT_LOCALE_STRING ==> array(4) {
[0]=> bool(true)
[1]=> bool(false)
[4]=> string(1) "0"
[5]=> string(3) "123"
}

*/
tasiot
10 個月前
另一種基於鍵值移除多維陣列中重複條目的解決方案…

<?php

function array_unique_multi(array $array, string $key): array
{
$unique = [];
foreach (
$array as $v) {
if (!
array_key_exists($v[$key], $unique)) {
$unique[$v[$key]] = $v;
}
}
return
array_values($unique);
}

// 用法
$unique = array_unique_multi($users, 'id');

?>

或是保留鍵值…

<?php

function array_unique_amulti(array $array, string $key): array
{
$keys = [];
$unique = [];
foreach (
$array as $k => $v) {
if (!isset(
$keys[$v[$key]])) {
$keys[$v[$key]] = true;
$unique[$k] = $v;
}
}
return
$unique;
}

?>
dirk dot avery a t gmail
15 年前
雖然 array_unique 並非設計用於多維陣列,但在 5.2.9 版本中確實有效。然而,在 5.2.5 版本中則無效。請注意。
csaba at alum dot mit dot edu
20 年前
以下是一個有效率且適應性強的 array_unique 實作,它總是保留具有給定值的第一個鍵值

<?php
function array_unique2(&$aray) {
$aHash = array();
foreach (
$aray as $key => &$val) if (@$aHash[$val]++) unset ($aray[$key]);
}
?>

它也適用於多維陣列。例如,如果您的陣列是一系列(多維)點,那麼您可以將 @$aHash[$val]++ 替換為 @$aHash[implode("X",$val)]++
如果您不希望陣列中有空洞,您可以在最後執行 array_merge($aray)。

Csaba Gabor
To Top