PHP數組查找操作的函數及技巧

PHP數組查找操作的函數:
1、bool in_array (mixed $needle , array $haystack [, bool $strict ] )
該函數的作用是在數組array中搜索指定的value值, $strict是可選參數,如果設置該參數爲 true ,則檢查搜索的數據與數組的值的類型是否相同,
如果不使用第三個參數,比較一個數字和字符串或者比較涉及到數字內容的字符串,則字符串會被轉換爲數值並且比較按照數值來進行,
所以當in_array的needle與array中的值類型是否相同還不確定時,最好設置in_array函數的第三個參數 strict = true,這樣在檢查的時候會檢查類型,數字與字符串就不會偷偷相等,也就避免類似這種問題。
如果比較一個整數和字符串,則字符串會被轉換爲整數。如果比較兩個數字字符串,則作爲整數比較。此規則也適用於 switch語句。
例1:
array('22',33,44,55,6)
in_array('22',$array) 
//這樣就會有一個把‘22’轉換爲22的操作,再進行比較
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true

例2:

$test = 0; 
$array = array('a', 'b', 'c');
if (in_array($test, $array, true)) {
    echo 'in array';
} else {
    echo 'no';
}
php比較數字和字符串時,會嘗試將字符串轉換爲數字再進行比較。 例子中的 'a', 'b', 'c' 轉成數字都是0,所以和0相等,in_array就返回了true。

null 或 string string 將 NULL 轉換爲 "",進行數字或詞彙比較
bool 或 null 任何其它類型 轉換爲 bool,FALSE < TRUE
object object 內置類可以定義自己的比較,不同類不能比較,相同類和數組同樣方式比較屬性(PHP 4 中),PHP 5 有其自己的說明
stringresource 或 number stringresource 或 number 將字符串和資源轉換成數字,按普通數學比較
array array 具有較少成員的數組較小,如果運算數 1 中的鍵不存在於運算數 2 中則數組無法比較,否則挨個值比較(見下例)
array 任何其它類型 array 總是更大
object 任何其它類型 object 總是更大


2、bool array_key_exists ( mixed $key , array $search ) ? 
爲什麼 array_key_exists 比 in_array快?
in_array 是順序查找
array_keys 是查哈希表
這裏我瞭解到PHP Array的KEY是進行HASH組織的,查詢很快。而VALUE是由KEY組織存放,本身沒有索引,每次查找都是遍歷。
 array_key_exists 會調用get_defined_vars判斷數組變量是否存在,而不是去遍歷。
array_key_exists in_array 查詢的東西都不一樣吧
array_key_exists 判斷是否有鍵值
array_key_exists(a,arr)->if(isset(arr[a]))就是true
in_array 需要去遍歷值 遍歷到了才跳出循環

3、mixed array_search ( mixed $needle , array $haystack [, bool $strict ] )
array_search() 函數與 in_array() 一樣,在數組中查找一個鍵值。如果找到了該值,則返回匹配該元素所對應的鍵名。如果沒找到,則返回 false。同樣如果第三個參數 strict 被指定爲 true,則只有在數據類型和值都一致時才返回相應元素的鍵名。
源碼中兩者調用一個函數。

4、isset 和 empty 查找數組

三種方式的語法區別

  • empty: 參數爲0或爲NULL時(如上面列子),empty均返回TRUE,詳細情況可以參見empty官方手冊
  • isset: 參數爲NULL時,返回FALSE,0與NULL在PHP中是有區別的,isset(0)返回TRUE
  • array_key_exists: 純粹的判斷數組鍵值對是否存在,無論值是多少

所以,從準確性的角度來看,array_key_exists是最準確的!

可以看到在大數據情況下,empty和isset的性能比array_key_exists快了2個數量級,差別還是很大。如果頻繁判斷,還是需要優化。產生這麼大性能差別的原因,個人猜測,可能是isset和empty作爲php語法結構不是函數,php解釋器做了優化,而array_key_exists作爲函數,沒有相關優化。具體原因,有待通過源碼考究。

三種方式的使用建議

(鑑於empty與isset性能類似,但是isset準確性較高,這裏就只比較isset與array_key_exists)

  • 如果數組不可能出現值爲NULL的情況,建議使用isset
  • 如果數組中經常出現值爲NULL的情況,建議使用array_key_exists
  • 如果數組中可能出現值爲NULL,但是較少的情況,建議結合isset與array_key_exists使用, 
  • 如“if (isset($arr[‘key’]) || array_key_exists(‘key’, $arr)){/*do somthing*/}”。此方法兼顧了性能和準確性,但是代碼變長了。

5、in_array優化

1.數組key與value翻轉,通過isset判斷key是否存在於數組中

public static function inArray($item, $array) {
    $flipArray = array_flip($array); 
    return isset($flipArray[$item]); 
}
2、用implode連接,直接用strpos判斷

用implode函數+逗號連起來,直接用strpos判斷。php裏面字符串取位置速度非常快,尤其是在大數據量的情況下。不過需要注意的是首尾都要加"," ,這樣比較嚴謹。如: ,user1,user2,user3, 查找的時候,查,user1,。還有strpos要用!== false,因爲第一個會返回0。示例如下:

public static function inArray($item, $array) { 
    $str = implode(',', $array); 
    $str = ',' . $str . ','; 
    $item = ',' . $item . ','; 
    return false !== strpos($item, $str) ? true : false; 
}

3、in_array 加第三個參數。
經過實際性能對比,在數據量不大的時候,比如小於1000,查找用哪一種都行,都不會成爲性能上的瓶頸。但當數據量比較大的時候,用 array_key_exists 比較合適。據測試 array_key_exist 要比 in_array 效率高十幾甚至幾十倍。

6、數組循環 
foreach 是最快的遍歷數組,其次是for 接下里是while


PHP數組添加和移除函數
1、mixed array_pop ( array &$array ) 
     彈出並返回 array 數組的最後一個單元,並將數組 array 的長度減一。如果 array 爲空(或者不是數組)將返回 NULL
<?php
    $stack = array("orange", "banana", "apple", "raspberry");
    $fruit = array_pop($stack);
    print_r($stack);
?>

經過此操作後,$stack 將只有 3 個單元:

Array
(
    [0] => orange
    [1] => banana
    [2] => apple
)

並且 rasberry 將被賦給 $fruit$fruit = "raspberry";

2、int array_push ( array &$array ,  mixed   $var [,  mixed   $... ] )
array_push() 將 array 當成一個棧,並將傳入的變量壓入 array 的末尾。array 的長度將根據入棧變量的數目增加。
相當於重複 $array[] = $var;
<?php
    $stack = array("orange", "banana");
    array_push($stack, "apple", "raspberry");
    print_r($stack);
?>
Note如果用 array_push() 來給數組增加一個單元,還不如用 $array[] = ,因爲這樣沒有調用函數的額外負擔。

3、 mixed   array_shift ( array &$array )
array_shift() 將 array 的第一個單元移出並作爲結果返回,將 array 的長度減一併將所有其它單元向前移動一位。所有的數字鍵名將改爲從零開始計數,文字鍵名將不變。如果 array 爲空(或者不是數組),則返回 NULL
其他和array_pop一樣

4、int array_unshift ( array &$array ,  mixed    $var [,  mixed    $... ] )
array_unshift() 將傳入的單元插入到 array 數組的開頭。注意單元是作爲整體被插入的,因此傳入單元將保持同樣的順序。所有的數值鍵名將修改爲從零開始重新計數,所有的文字鍵名保持不變。    返回 array 數組新的單元數目。
<?php
    $queue = array("orange", "banana");
    array_unshift($queue, "apple", "raspberry");
?>
Array
(
[0] => apple
[1] => raspberry
[2] => orange
[3] => banana
)

PHP數組回調方法

1、bool array_walk ( array &$array , callback $funcname [, mixed $userdata ] ) 對數組中的每個成員應用用戶函數

將用戶自定義函數 funcname 應用到 array 數組中的每個單元。典型情況下 funcname 接受兩個參數。array 參數的值作爲第一個,鍵名作爲第二個。如果提供了可選參數 userdata,將被作爲第三個參數傳遞給 callback funcname
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
 
function test_alter(&$item1, $key, $prefix)
{
    $item1 = "$prefix: $item1";
}
 
function test_print($item2, $key)
{
    echo "$key. $item2<br />\n";
}
 
echo "Before ...:\n";
array_walk($fruits, 'test_print');
 
array_walk($fruits, 'test_alter', 'fruit');
echo "... and after:\n";
 
array_walk($fruits, 'test_print');

2、array_walk_recursive — 對數組中的每個成員遞歸地應用用戶函數 ,同上一個函數,只是這個函數會遞歸調用。
<?php
$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => 'lemon');
 
function test_print($item, $key)
{
    echo "$key holds $item\n";
}
 
array_walk_recursive($fruits, 'test_print');
?>
以上例程會輸出:
 
a holds apple
 
b holds banana
sour holds lemon

注意上例中的鍵 'sweet' 並沒有顯示出來。任何其值爲數組的鍵都不會被傳遞到回調函數中去。

3、array array_map ( callback $callback , array $arr1 [, array $... ] )
array_map() 返回一個數組,該數組包含了 arr1 中的所有單元經過 callback 作用過之後的單元。callback 接受的參數數目應該和傳遞給 array_map() 函數的數組數目一致。
Example #1 array_map() 例子
<?php
function cube($n)
{
    return($n * $n * $n);
}
 
$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
?>
這使得 $b 成爲:
 
Array
(
[0] => 1
[1] => 8
[2] => 27
 
[3] => 64
[4] => 125
)

Example #2 array_map() - 使用更多的數組
 
<?php
function show_Spanish($n, $m)
{
    return("The number $n is called $m in Spanish");
}
 
function map_Spanish($n, $m)
{
    return(array($n => $m));
}
 
$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");
 
$c = array_map("show_Spanish", $a, $b);
print_r($c);
 
$d = array_map("map_Spanish", $a , $b);
print_r($d);
?>
以上例程會輸出:
// printout of $c
Array
(
[0] => The number 1 is called uno in Spanish
[1] => The number 2 is called dos in Spanish
[2] => The number 3 is called tres in Spanish
[3] => The number 4 is called cuatro in Spanish
[4] => The number 5 is called cinco in Spanish
)


PHP數組其他方法
1、bool shuffle ( array &$array ) — 將數組打亂
2、array range ( mixed $low , mixed $high [, number $step ]  )  建立一個包含指定範圍單元的數組
range(1,20) 產生一個20個元素的數組
range(1,20,2) 產生一個 20/2 個元素的數組,每個間隔是2
3、array compact ( mixed $varname [, mixed $... ] ) 把變量轉換爲數組。
$name = 'caida';
$sax = 20;
$phone = '139...';
 
$arr = array('name', 'sax', 'phone');
$newarr = compact($arr);
print_r($newarr);
print_r(compact('name'));

4、int extract ( array $var_array [, int $extract_type [, string $prefix ]] ) 把數組轉換成變了。
$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");
 
extract($var_array);
echo $size; #medium
5、array array_chunk ( array $input , int $size [, bool $preserve_keys ] ) 將一個數組分割成多個

$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));

6、array array_count_values ( array $input  )  統 計數組中所有的值出現的次數

7、array_flip — 交換數組中的鍵和值

8、array array_filter ( array $input [, callback $callback ] )
array_filter() 依次將 input 數組中的每個值傳遞到 callback 函數。如果 callback 函數返回 TRUE,則 input 數組的當前值會被包含在返回的結果數組中。數組的鍵名保留不變。
<?php
function odd($var)
{
    return($var % 2 == 1);
}
 
function even($var)
{
    return($var % 2 == 0);
}
 
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
 
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
Odd :
 
Array
 
(
 
[a] => 1
[c] => 3
[e] => 5
)
 
Even:
 
Array
(
[0] => 6
[2] => 8
[4] => 10
 
[6] => 12
)
9、array array_merge ( array $array1 [, array $array2 [, array $... ]] )  一維數組
      array array_merge_recursive ( array $array1 [, array $... ] )          多維數組

array_merge() 將一個或多個數組的單元合併起來,一個數組中的值附加在前一個數組的後面。返回作爲結果的數組。如果輸入的數組中有相同的字符串鍵名,則該鍵名後面的值將覆蓋前一個值。然而,如果數組包含數字鍵名,後面的值將不會覆蓋原來的值,而是附加到後面。如果只給了一個數組並且該數組是數字索引的,則鍵名會以連續方式重新索引。


10、mixed array_rand ( array $input [, int $num_req ] ) 從數組中隨機取出一個或多個單元

11、array array_slice ( array $array , int $offset [, int $length [, bool $preserve_keys ]] )
array_slice() 返回根據 offset 和 length 參數所指定的 array 數組中的一段序列。 第三個參數爲TRUE是不重建數組鍵。
$input = array("a", "b", "c", "d", "e");
 
$output = array_slice($input, 2);      // returns "c", "d", and "e"
$output = array_slice($input, -2, 1);  // returns "d"
$output = array_slice($input, 0, 3);   // returns "a", "b", and "c"
 
// note the differences in the array keys
print_r(array_slice($input, 2, -1));
print_r(array_slice($input, 2, -1, true));

12、array array_unique ( array $array )
注意鍵名保留不變。array_unique() 先將值作爲字符串排序,然後對每個值只保留第一個遇到的鍵名,接着忽略所有後面的鍵名。這並不意味着在未排序的 array 中同一個值的第一個出現的鍵名會被保留。

PHP數組常用方法
1、一個值,對應其他的值。(刪除指定值得數組)
$a= array(aa, bb, cc,);
foreach($a as $k=>$v){
$s[$v] = $a;
array_splice($s[$v], $k, 1); 
 
}
print_r($s);
Array(
    [aa] => Array(
        [0] => bb
        [1] => cc
    )
 
    [bb] => Array(
        [0] => aa
        [1] => cc
    )
    [cc] => Array(
        [0] => aa
        [1] => bb
    )
)

只適用於索引數組。
1.索引下標會重建
$a= array(aa, bb, cc,);
array_splice($a,array_search('bb',$a),1);
print_r($a);
2.索引下標不會重建
$a= array(aa, bb, cc,);
unset($a[1]);
print_r($a);
適用於關聯索引,刪除關聯數組用unset
$a=array("a"=>"Dog","b"=>"Cat","c"=>"Horse"); 
print_r($a); 
unset($a[array_search("Cat",$a)]);//array_search("Cat",$a)按元素值返回鍵名。去除後保持索引 
print_r($a); 



 
2 、相同鍵名合併到一起
$a = array(
array('60'=>61),
array('60'=>62),
array('61'=>63),
array('61'=>64),
array('62'=>65),
array('63'=>66),
);
方法1:
$arr = array();
foreach($a as $key=>$v){
foreach ($v as $k=>$vv) {
$arr[$k][]=$vv;
}
 
}
Array
(
    [60] => Array(
        [0] => 61
        [1] => 62
    )        
    [61] => Array(
        [0] => 63
        [1] => 64
    )
    [62] => Array(
        [0] => 65
    )
 
    [63] => Array(
        [0] => 66
    )
)
方法2:
$result = array ();
foreach($a as $val) {
     foreach($val as $k => $v) {
         if( isset($result[$k])){
             $result[$k] = $result[$k].','.$v;
          }else{
             $result [ $k ] = $v ;
           }
      }
}
結果:
Array
(
    [ 60 ] = > 61 , 62
    [ 61 ] = > 60 , 62
    [ 62 ] = > 60 , 61
    [ 63 ] = > 64
    [ 64 ] = > 63
)

4、去掉相同值的數組並是排序
 Array
(
    [ 0 ] = > 60 , 61 , 62
    [ 1 ] = > 61 , 60 , 62
    [ 2 ] = > 62 , 60 , 61
    [ 3 ] = > 63 , 64
    [ 4 ] = > 64 , 63
)
處理函數: //寫的比較好
         function a_array_unique( $ array ){
              $out =  array ();
              foreach( $ array as $key = > $value ) {
                  $arr = explode( ',' , $value );
                  sort( $arr );
                  $sovalue  = join( ',' , $arr );
                      if( ! in_array( $sovalue ,  $out )){
                          $out [ $key ] =       $value ;
                        }
                    }
                       return$out ;
                }
                 $ars  = a_array_unique( $result ); 
 
結果:
Array
(
    [ 0 ] = > 60 , 61 , 62
    [ 3 ] = > 63 , 64
)


5、取出二維數組中的最大的值,(對應的鍵)
例如數組:Array ( [34] => 2 [7] => 100 ) PHP 如何獲取值最大的鍵值 這個例子中應該返回7
$arr=array(34=>2,7=>100);//定義一個數組
$t=max($arr);//獲取最大的值
$brr=array_flip($arr);//將數組鍵與值互換
echo $brr[$t];//輸出結果,即爲原數組最大值的鍵

 
6、PHP刪除數組中指定的值
$arr = array ( "a" , "b" , "c" , "d" );
function isHave ( $ var ){
if ( $ var != "b" ) return true ;
}
array_filter ( $arr , "isHave" );


7、數組按照中文排序
     function     utf8_array_asort( & $ array ) {
        if ( ! isset ( $ array ) || ! is_array( $ array )) {
            return false ;
    }
        foreach ( $ array        as     $k = > $v ) {
         $ array [ $k ] = iconv( 'UTF-8' ,     'GBK//IGNORE' , $v );
    }
    asort( $ array );
        foreach ( $ array        as     $k = > $v ) {
         $ array [ $k ] = iconv( 'GBK' ,     'UTF-8//IGNORE' ,  $v );
    }
        return true ; }
 

8、定義php數組二維數組的值的和
$modelArr [ $ks ][ 'count' ] +=  $ms [ 'query_count' ];  會報錯誤,說conut未定義。
用下面這個方法:
$modelArr [ $ks ][ 'count' ] = array_sum( $ms [ 'query_count' ]);

 
9、PHP裏判斷2個數組值是否相同 不相同的值取出來放進另外一個數組怎麼寫?
array_merge(array_diff($arr1, array_intersect($arr1, $arr2)), array_diff($arr2, array_intersect($arr1, $arr2)));

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章