1. php array_flip() 刪除數組重復元素,
如果用於一維索引數組,好理解。
[root@BG-DB:~]$more arr.php
<?php
$arr = array('a','b','c','a','b','b');
var_dump(
array_flip(
array_flip($arr) ));
?>
[root@BG-DB:~]$
[root@BG-DB:~]$php arr.php
array(3) {
[3]=>
string(1) "a"
[5]=>
string(1) "b"
[2]=>
string(1) "c"
}
[root@BG-DB:~]$
說明:
1)
array_unique() 也可以達到相同的目的,但是
據說array_unique()效率很低,遠不及array_flip()
2) 據測試,上述兩個函數都一般不可以用於
二維數組或者
關聯數組,否則結果未知,例如:
當用array_unique()用於關聯數組的時候,系統應該是簡單的執行了索引覆蓋,所以
后面的元素會覆蓋前面的元素。而往往需要前面的元素不被覆蓋,后面的元素丟棄。
[root@BG-DB:~]$more arr.php
<?php
$arr = array('a'=>123,'b'=>456,'c'=>'def','a'=>123,'b'=>'ccc','c'=>'abc');
var_dump(array_unique($arr));
?>
[root@BG-DB:~]$php arr.php
array(3) {
["a"]=>
int(123)
["b"]=>
string(3) "ccc"
["c"]=>
string(3) "abc"
}
[root@BG-DB:~]$
理論上如果用array_flip()執行前面的例子,就會出問題了,因為索引鍵值不會是一個數組。但是事實上結果確和上面一樣,也是
后面的覆蓋前面的,可以理解。如下:
[root@BG-DB:~]$more arr.php
<?php
$arr = array('a'=>123,'b'=>456,'c'=>'def','a'=>123,'b'=>'ccc','c'=>'abc');
var_dump(array_flip(array_flip($arr)));
?>
[root@BG-DB:~]$
[root@BG-DB:~]$php arr.php
array(3) {
["a"]=>
int(123)
["b"]=>
string(3) "ccc"
["c"]=>
string(3) "abc"
}
[root@BG-DB:~]$
但是,當
數組維數變多的時候,上面的函數就有點難理解了,但是道理都是:
后面的覆蓋前面的方法去重。如下:
[root@BG-DB:~]$more arr.php
<?php
$arr = array('a'=>123,'b'=>
Array("x"=>"a","y"=>'b'),'c'=>'def','a'=>123,'b'=>'ccc','c'=>'abc');
var_dump(array_flip(array_flip($arr)));
?>
[root@BG-DB:~]$php arr.php
array(3) {
["a"]=>
int(123)
["b"]=>
string(3) "ccc"
["c"]=>
string(3) "abc"
}
[root@BG-DB:~]$
===============================
后來干脆自己寫了個
多維去重的函數,是前面出現的元素不被后面覆蓋,還是運行有問題。
對於下面的數組,也就是數值鍵值還是一個數組,array_flip()和array_unique()就顯得黔驢技窮了,如下:
[root@BG-DB:~]$more arr.php
<?php
$arr = Array(
Array("user"=>"wjj","age"=>20),
Array("user"=>"wu","age"=>21),
Array("user"=>"jun","age"=>22),
Array("user"=>"
wu","age"=>20000),
Array("user"=>"jie","age"=>23),
Array("user"=>"
wjj","age"=>200),
);
var_dump(array_flip(array_flip($arr)));
//var_dump(array_unique($arr));
?>
[root@BG-DB:~]$php arr.php
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/arr.php on line 10
array(0) {
}
[root@BG-DB:~]$
於是自己寫了個方法,一直搞不明白運行為毛還有問題,為此和boss爭論的面紅耳赤,代碼形如:
回來后仔細一想,就這點破事,哎!
[root@BG-DB:~]$more arr.php
<?php
$arr = Array(
Array("user"=>"wjj","age"=>20),
Array("user"=>"wu","age"=>21),
Array("user"=>"jun","age"=>22),
Array("user"=>"
wu","age"=>20000),
Array("user"=>"jie","age"=>23),
Array("user"=>"
wjj","age"=>200),
);
$A = Array();
foreach($arr AS &$val){
if( isset($A[$val['user']]) ){
unset($val);
//$val = Array();
continue;
}else{
$A[$val['user']] = true;
}
}
var_dump($arr);
?>
[root@BG-DB:~]$php arr.php
array(6) {
[0]=>
&array(2) {
["user"]=>
string(3) "
wjj"
["age"]=>
int(20)
}
[1]=>
&array(2) {
["user"]=>
string(2) "
wu"
["age"]=>
int(21)
}
[2]=>
&array(2) {
["user"]=>
string(3) "jun"
["age"]=>
int(22)
}
[3]=>
array(2) {
["user"]=>
string(2) "
wu"
["age"]=>
int(20000)
}
[4]=>
&array(2) {
["user"]=>
string(3) "jie"
["age"]=>
int(23)
}
[5]=>
array(2) {
["user"]=>
string(3) "
wjj"
["age"]=>
int(200)
}
}
[root@BG-DB:~]$
上面的代碼
把unset($val); 改成 $val = Array(); ,后打印如下:
[root@BG-DB:~]$
[root@BG-DB:~]$php arr.php
array(6) {
[0]=>
&array(2) {
["user"]=>
string(3) "wjj"
["age"]=>
int(20)
}
[1]=>
&array(2) {
["user"]=>
string(2) "wu"
["age"]=>
int(21)
}
[2]=>
&array(2) {
["user"]=>
string(3) "jun"
["age"]=>
int(22)
}
[3]=>
&array(0) {
}
[4]=>
&array(2) {
["user"]=>
string(3) "jie"
["age"]=>
int(23)
}
[5]=>
&array(0) {
}
}
[root@BG-DB:~]$
尼瑪看上去
好像是unset()不支持銷毀一個多維數組,只支持銷毀單一的原子元素,想了幾次還真覺得是這個樣子,后來測試發現不是,
原來unset()支持一次性銷毀一個多維數組,證據如下:
[root@BG-DB:~]$more arr1.php
<?php
$arr = Array(
Array("user"=>"wjj","age"=>20),
Array("user"=>"wu","age"=>21),
Array("user"=>"jun","age"=>22),
Array("user"=>"wu","age"=>20000),
Array("user"=>"jie","age"=>23),
Array("user"=>"wjj","age"=>200),
);
unset($arr);
var_dump($arr);
?>
[root@BG-DB:~]$
[root@BG-DB:~]$php arr1.php
PHP Notice:
Undefined variable: arr in /root/arr1.php on line 13
NULL
[root@BG-DB:~]$
最后仔細想想,發現原來是這樣
:foreach()循環,我銷毀的只是臨時變量$val,而並不是真正的數組元素,即使我
用&引用,只是銷毀了引用指針,而實際存在數組中元素還是原封不動的,后來代碼改成如下,尼瑪還沒達到預期結果:
[root@BG-DB:~]$more arr.php
<?php
$arr = Array(
Array("user"=>"wjj","age"=>20),
Array("user"=>"wu","age"=>21),
Array("user"=>"jun","age"=>22),
Array("user"=>"
wu","age"=>20000),
Array("user"=>"jie","age"=>23),
Array("user"=>"
wjj","age"=>200),
);
$A = Array();
$index = 0;
foreach($arr AS $val){
if( isset($A[$val['user']]) ){
unset(
$arr[$index]);
continue;
}else{
$A[$val['user']] = true;
}
$index++;
}
var_dump($arr);
?>
[root@BG-DB:~]$php arr.php
array(4) {
[0]=>
array(2) {
["user"]=>
string(3) "
wjj"
["age"]=>
int(20)
}
[1]=>
array(2) {
["user"]=>
string(2) "wu"
["age"]=>
int(21)
}
[2]=>
array(2) {
["user"]=>
string(3) "jun"
["age"]=>
int(22)
}
[5]=>
array(2) {
["user"]=>
string(3) "
wjj"
["age"]=>
int(200)
}
}
[root@BG-DB:~]$
不解,原因是當我 unset($arr[$index]); 后而我的$index自動加1,但此時數組長度確減少了,最后的一個數組元素的下標也減少,
每剔除一個元素,就會跳過一個元素。上面的代碼最好用komodo單步跟蹤一下,不理解為什么結果是這樣的。
最后改成如下,就可以了:
[root@BG-DB:~]$more arr.php
<?php
$arr = Array(
Array("user"=>"wjj","age"=>20),
Array("user"=>"wu","age"=>21),
Array("user"=>"jun","age"=>22),
Array("user"=>"wu","age"=>20000),
Array("user"=>"jie","age"=>23),
Array("user"=>"wjj","age"=>200),
);
$A = Array();
$arrNew = Array();
foreach($arr AS $val){
if( isset($A[$val['user']]) ){
continue;
}else{
$A[$val['user']] = true;
$arrNew[] = $val;
}
}
var_dump($arrNew);
?>
[root@BG-DB:~]$
[root@BG-DB:~]$php arr.php
array(4) {
[0]=>
array(2) {
["user"]=>
string(3) "wjj"
["age"]=>
int(20)
}
[1]=>
array(2) {
["user"]=>
string(2) "wu"
["age"]=>
int(21)
}
[2]=>
array(2) {
["user"]=>
string(3) "jun"
["age"]=>
int(22)
}
[3]=>
array(2) {
["user"]=>
string(3) "jie"
["age"]=>
int(23)
}
}
[root@BG-DB:~]$
==========================================
php array_flip() 刪除數組重復元素
在PHP中,用於刪除數組中重復元素有一個可用的函數,那就是 array_unique(), 但是它並不是一個最高效的方法,使用array_flip() 函數將比array_uniqure()在速度上高出五倍左右。
方法如下:
$arr = array(…………) ;//假設有一萬個元素的數組,里面有重復的元素。
$arr = array_flip(array_flip($arr)); //這樣便可以刪除重復元素。
究竟是怎么回事呢?來看下array_flip()的作用:array_flip()用於將一個數組的每個元素的鍵和值交換,如:
$arr1 = array (”age” => 30, “name” => “快樂園”);
$arr2 = array_flip($arr1); //$arr2 就是 array(30 => “age”, “快樂園” => “name”);
在PHP的數組中,允許不同的元素可以取同一個值,但不允許同一個鍵名被不同的元素使用,如:
$arr1 = array (”age” => 30, “name” => “快樂園”, “age” => 20); “age” => 20將會取代”age” => 30
$arr1 = array (”name” => “快樂園”, “age” => 45);
這里 $arr1與$arr2 是相等的。
於是,我們便可以知道,為什么 array_flip(array_flip($arr)) 可以刪除數組中重復的元素了。首先,$arr里的值會變成鍵名,因為值是有重復的,變成鍵名之后這些重復的值便成了重復的鍵名,PHP引擎將重復的鍵名刪除,只保留最后一個。如:
$arr1 = array (”age” => 30, “name” => “快樂園”, “age” => 20);
$arr1 = array_flip($arr1); //$arr1 變成了 array(”快樂園” => “name”, 20 => “age”);
//再把 $arr1 的鍵名與值還復:
$arr1 = array_flip($arr1);
上面的代碼寫得簡潔一些就是: $arr1 = array_flip(array_flip($arr1));
=============================================