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 有其自己的说明

string,resource 或 number

string,resource 或 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 [] =  $var ;


<?php

    $stack = array("orange", "banana");

    array_push($stack, "apple", "raspberry");

    print_r($stack);

?>

Note: 如果用 array_push()



3、mixed   array_shift ( array &$array )


array_shift()


其他和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)));