array_map()的妙用

关于array_map函数,还有一篇文章作为补充,详情见此:https://liyangweb.com/php/299.html

array_map在php手册中的说明是这样的: 

array_map — 将回调函数作用到给定数组的单元上

说明
array array_map ( callback $callback , array $arr1 [, array $… ] )
array_map() 返回一个数组,该数组包含了 arr1 中的所有单元经过 callback 作用过之后的单元。callback 接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

 

很容易理解吧,不过这解释也有点太言简意赅了,很多特性和用法都只字未提,下面由我来为大家细细道来.

最简单的用法:

    $arr = array(1,2,3,4,5,6);
    function a($val){
        return $val*2;
    }
    $new_arr = array_map('a',$arr);
    var_dump($new_arr);

这段代码的意思是把数组$arr中的每个值分别传到函数a中,并把值乘以2后返回.返回值是这样的:

array (size=6)
  0 => int 2
  1 => int 4
  2 => int 6
  3 => int 8
  4 => int 10
  5 => int 12

 

这也是大部分人都会使用的一个用法.

当然还有传递多个array的用法:

    $arr1 = array(1,2,3,4,5,6);
    $arr2 = array(7,8,9,10,11,12);
    function a($val,$val2){
        return $val*$val2;
    }
    $new_arr = array_map('a',$arr1, $arr2);
    var_dump($new_arr);

看到我的写法,大家也肯定可以猜到返回值:

array (size=6)
  0 => int 7
  1 => int 16
  2 => int 27
  3 => int 40
  4 => int 55
  5 => int 72

 

两个数组的值被按照顺序相乘了,这里要注意一点,两个数组的长度一定要一致,否则会自动用空内容来补足到相同的长度.

说了两个基本的方法,下面给大家介绍一种比较特殊的使用方法,那就是callback传递一个null:

    $arr1 = array(1,2,3,4,5,6);
    $arr2 = array(7,8,9,10,11,12);
    function a($val,$val2){
        return $val*$val2;
    }
    $new_arr = array_map(null,$arr1, $arr2);
    var_dump($new_arr);


返回值是这样的:

array (size=6)
  0 => 
    array (size=2)
      0 => int 1
      1 => int 7
  1 => 
    array (size=2)
      0 => int 2
      1 => int 8
  2 => 
    array (size=2)
      0 => int 3
      1 => int 9
  3 => 
    array (size=2)
      0 => int 4
      1 => int 10
  4 => 
    array (size=2)
      0 => int 5
      1 => int 11
  5 => 
    array (size=2)
      0 => int 6
      1 => int 12


两个同样位置的值被组合成了一个数组,那如果我们传递的是一个数组呢?那么该写法毫无意义,数组又被原样返了回来.

还有一个非常方便的特性,匿名函数,对于实现简单,也没有太大复用价值的函数,匿名函数是一个不错的选择.

我们来把第一个例子小小的优化一下:

    $arr = array(1,2,3,4,5,6);
    $new_arr = array_map(function($val){return $val*2},$arr);
    var_dump($new_arr);

是不是简单了很多?
在面向对象编程思想日益壮大的今天,我们的项目中可能完全消失了函数的概念,取而代之的是类和方法,那么array_map()就不能胜任了吗?答案当然是否定的,可惜手册中没有提到,网上的资料也比较少,那么这里就是本博文的意义所在.

    class Test
    {
        static function a($val)
        {
            return $val*2;
        }
    }
    
    $arr1 = array(1,2,3,4,5,6);
    $new_arr2 = array_map(array('Test','a'),$arr1);
    var_dump($new_arr2);

上面的例子a方法是一个静态方法,所以例子中没有new一个对象的操作.
array_map()的第一个参数可以是一个数组,数组的第一个值是类的名字,第二个参数是类中的一个静态方法.
那如果就是一个普通方法呢?

 

    class Test
    {
        public function aa($val)
        {
            return $val*2;
        }
    }
    
    $arr1 = array(1,2,3,4,5,6);
    $new_arr2 = array_map(array(new Test(),'aa'),$arr1);
    var_dump($new_arr2);

 使用起来也毫无压力嘛.
那如果是在类的内部调用呢?

 

   class Test
    {
        static function a($val)
        {
            return $val*2;
        }
        public function aa($val)
        {
            return $val*2;
        }

        public function TestA()
        {
            $arr1 = array(1,2,3,4,5,6);
            //这里很奇怪,不论是否是静态方法,下面三种写法均可行
            $new_arr = array_map(array($this, 'a'), $arr1);
            $new_arr = array_map(array('self', 'a'), $arr1);
            $new_arr = array_map(array('Test', 'a'), $arr1);
            return $new_arr;
        }
        public function TestAa()
        {
            $arr1 = array(1,2,3,4,5,6);
            //这里很奇怪,不论是否是静态方法,下面三种写法均可行
            $new_arr = array_map(array($this, 'aa'), $arr1);
            $new_arr = array_map(array('self', 'aa'), $arr1);
            $new_arr = array_map(array('Test', 'aa'), $arr1);
            return $new_arr;
        }
    }
    
    $test = new Test();
    $new_arr1 = $test->TestA();
    $new_arr2 = $test->TestAa();
    var_dump($new_arr1);
    var_dump($new_arr2);

在类中传递两个参数的方法和外面是一样的,这里不就不赘述了.好啦,文章就写到这里,相信对array_map()你已经可以信手拈来了,合理的利用array_map()可以减少很多不必要的循环,很有效的提升代码效率和可读性.

4 comments:

评论已关闭。