美文网首页
PHP强化之03 - 数组 Array(新)

PHP强化之03 - 数组 Array(新)

作者: 四月不见 | 来源:发表于2022-01-09 22:11 被阅读0次

    ----- 最后更新【2022-01-09】-----

    PHP强化系列--目录

    本文目录结构预览:

    • 一、简介
    • 二、语法
      1、定义数组
      2、数组运算符
    • 三、类型转换
    • 四、数组解包
    • 五、内部指针
    • 六、数组遍历
      1、for循环
      2、foreach循环
      3、while, list(), each()组合循环
      4、三种遍历方式的区别
      5、for, next(), key(), current()组合
    • 七、常用函数
      1、对数组进行排序
      2、数组与字符串间的转换
      3、数组的运算
      4、数组的键与值
      5、数组生成器
      6、回调函数的应用
    • 八、经典实例
    • 九、参考

    一、简介

    PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量)、散列表(是映射的一种实现)、字典、集合、栈、队列以及更多可能性。由于数组元素的值也可以是另一个数组,树形结构和多维数组也是允许的。

    可以用 array()语言结构来新建一个数组。自 5.4 起可以使用短数组定义语法,用 [] 替代 array()。

    $array = array(
        0 => "bar",
        1 => "foo"
    );
    
    // 自 PHP 5.4 起
    $array = [
        0 => "bar",
        1 => "foo"
    ];
    

    本文内容可能会比较多,为了方面提前知道有哪些内容,这里先作一个简要的展示:
    简介->语法->类型转换->数组解包->内部指针->数组遍历->常用函数->经典实例->参考

    二、语法

    1、定义数组

    组成数组的 key 可以是 integer 或者 string,而 value 可以是任意类型。

    此外 key 会有如下的强制转换:
    1)String 中包含有效的十进制 int,除非数字前面有一个 + 号,否则将被转换为 int 类型。例如键名 "8" 实际会被储存为 8。另外, "08" 不会被强制转换,因为它不是一个有效的十进制整数。
    2)Float 也会被转换为 int ,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
    3)Bool 也会被转换成 int。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
    4)Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
    5)Array 和 object 不能 被用为键名。坚持这么做会导致警告:Illegal offset type。

    如果在数组定义时多个元素都使用相同键名,那么只有最后一个会被使用,其它的元素都会被覆盖。

    php > $array = array(
           1    => "a",
           "1"  => "b",
           1.5  => "c",
           true => "d",
      );
    php > var_dump($array);
    array(1) {
      [1]=>
      string(1) "d"
    }
    

    注意:
    在 PHP 8.0.0 之前,方括号和花括号可以互换使用来访问数组单元(例如 $array[42] 和 $array{42} 在上例中效果相同)。 花括号语法在 PHP 7.4.0 中已弃用,在 PHP 8.0.0 中不再支持。

    # php < 8.0
    php > $arr = [ 'a'=>123 ];
    php > echo $arr['a'];
    123
    php >  echo $arr{'a'};
    123
    
    # php >= 8.0
    php > $arr = [ 'a'=>123 ];
    php > echo $arr['a'];
    123
    php > echo $arr{'a'};   # 致命错误
    Fatal error: Array and string offset access syntax with curly braces is no longer supported in php shell code on line 1
    

    注意:该始终在用字符串表示的数组索引上加上引号。例如用 $foo['bar'] 而不是 $foo[bar]。(但用不着给键名为 常量 或 变量 的加上引号,否则会使 PHP 不能解析它们。)

    # php < 8.0
    php >  $arr[a]=1111111111111111;    # Warning级错误
    PHP Warning:  Use of undefined constant a - assumed 'a' (this will throw an Error in a future version of PHP) in php shell code on line 1
    
    # php >= 8.0
    php > $arr[a]=11111111111;   #致命错误
    Warning: Uncaught Error: Undefined constant "a" in php shell code:1
    Stack trace:
    #0 {main}
      thrown in php shell code on line 1
    

    注意:但是在字符串中引用数组时则不需要加给索引加引号

    php > $arr['a'] = 123;
    php > echo "My array: $arr[a].";   # 正确,但不建议这种写法,容易与常量混淆
    My array: 123.
    php > echo "My array: $arr['a'].";   # 语法错误
    Parse error: syntax error, unexpected string content "", expecting "-" or identifier or variable or number in php shell code on line 1
    php > echo "My array: {$arr['a']}.";  # 正确,官方建议
    My array: 123.
    

    2、数组运算符

    例子 名称 结果
    $a + $b 联合 $a 和 $b 的联合。
    $a == $b 相等 如果 $a 和 $b 具有相同的键/值对则为 TRUE。
    $a === $b 全等 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE。
    $a != $b 不等 如果 $a 不等于 $b 则为 TRUE。
    $a <> $b 不等 如果 $a 不等于 $b 则为 TRUE。
    $a !== $b 不全等 如果 $a 不全等于 $b 则为 TRUE。

    +运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略。

    php > $a = array("a" => "apple", "b" => "banana");
    php > $b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
    php > $c = $a + $b;
    php > var_dump($c);
    array(3) {
      ["a"]=>
      string(5) "apple"
      ["b"]=>
      string(6) "banana"
      ["c"]=>
      string(6) "cherry"
    }
    

    数组中的单元如果具有相同的键名和值则比较时相等。

    php > $a = array("apple", "banana");
    php > $b = array(1 => "banana", "0" => "apple");
    php > var_dump($a == $b); 
    bool(true)
    php > var_dump($a === $b);
    bool(false)
    

    三、类型转换

    对于任意 integerfloatstringbooleanresource 类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array) $scalarValuearray($scalarValue) 完全一样。

    如果一个 object 类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外: 私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NUL 字节。 未初始化的类型属性将会被丢弃。如下:

    php > class A {
             private $B = 111;
             protected $C = 222;
             public $D = 333;
        
             function __construct()
             {
                 $E = 444;
                 $this->{1} = 555;
             }
         }
    php > var_export((array) new A());
    array (
      '' . "\0" . 'A' . "\0" . 'B' => 111,
      '' . "\0" . '*' . "\0" . 'C' => 222,
      'D' => 333,
      1 => 555,
    )
    php > var_dump((array) new A());
    array(4) {
      [" A B"]=>
      int(111)
      [" * C"]=>
      int(222)
      ["D"]=>
      int(333)
      [1]=>
      int(555)
    }
    

    将 NULL 转换为 array 会得到一个空的数组。

    四、数组解包

    在 array 定义时,用 ... 前缀的一个 array 可以被展开到当前位置。 只有实现了 Traversable(可以使用 foreach 进行遍历)的数组和对象才能被展开。 PHP 7.4.0 开始可以使用 ... 解包 array。

    它可以多次使用,在 ... 操作符前后都可以添加常规元素:

    php > $arr1 = [111, 222, 333];
    php > $arr2 = ['apple','pear'];
    php > $arr3 = [0,...$arr1,...$arr2,444];
    php > var_dump($arr3);
    array(7) {
      [0]=>
      int(0)
      [1]=>
      int(111)
      [2]=>
      int(222)
      [3]=>
      int(333)
      [4]=>
      string(5) "apple"
      [5]=>
      string(4) "pear"
      [6]=>
      int(444)
    }
    

    ... 操作符解包 array 时也遵守函数 array_merge() 的语义。 也就是说,key 为字符时,后面的字符键会覆盖之前的字符键;key 为 integer 时则会重新编号:

    注意:
    在 PHP 8.1 之前,带有 string 键的 array 无法解包。如:
    $arr1 = ['a'=>'apple', 'b'=>'pear']; $arr2 = ['cc', ...$arr1];
    这样会报错,因为数组$arr1的存在字符串键。

    最新版本的 PHP 8.1+ ,已经加入了对字符串键控数组的数组解包支持:

    php > $arrayA = ['a' => 1];
    php > $arrayB = ['b' => 2];
    php > $result = ['a' => 0, ...$arrayA, ...$arrayB];
    php > var_dump($result);
    array(2) {
      ["a"]=>
      int(1)
      ["b"]=>
      int(2)
    }
    

    五、内部指针

    方法 说明
    reset 将数组的内部指针指向第一个单元,并返回第一个数组单元的值
    current 返回数组中的当前单元的值
    next 将数组中的内部指针向前移动一位,并返回下一个单元的值
    prev 将数组的内部指针倒回一位,并返回前一个单元的值
    each 返回数组中当前的 键/值 对,并将数组指针向前移动一步(本函数已废用)
    end 将数组的内部指针指向最后一个单元,并返回最后一个数组单元的值
    key 返回数组中当前单元的键名

    例1、

    php > $array = array('step one', 'step two', 'step three', 'step four');
    php > echo current($array);
    step one
    php > next($array);
    php > next($array);
    php > echo current($array);
    step three
    php > reset($array);
    php > echo current($array);
    step one
    

    例2:

    php > $foo = array("Robert" => "Bob", "Seppo" => "Sepi");
    php > print_r(each($foo));
    Array
    (
        [1] => Bob
        [value] => Bob
        [0] => Robert
        [key] => Robert
    )
    php > print_r(each($foo));
    Array
    (
        [1] => Sepi
        [value] => Sepi
        [0] => Seppo
        [key] => Seppo
    )
    

    六、数组遍历

    1、for循环

    适用情况,数组的下标为从0开始的连续索引。

    php > $arr = ['a','b','c','d','e','f','g'];
    php > $count = count($arr);
    php > for($i = 0; $i < $count; $i++){
              echo $arr[$i] . "==";
          }
    a==b==c==d==e==f==g==
    

    2、foreach循环

    foreach为php遍历数组最常用的方法。

    php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
    php > foreach($arr as $k=>$v){
              echo " $k: $v  ";
          }
    【0: 12 】【a: 8 】【6: 10 】【b: 3 】【7: 80 】
    

    可以通过引用传递 array 的值来直接更改数组的值。

    php > $colors = array('red', 'blue', 'green', 'yellow');
              foreach ($colors as &$color) {
              $color = strtoupper($color);
          }
    
    php > unset($color);   /* 确保后面对 $color 的写入不会修改最后一个数组元素 */
    php > print_r($colors);
    Array
    (
        [0] => RED
        [1] => BLUE
        [2] => GREEN
        [3] => YELLOW
    )
    

    3、while, list(), each()组合循环

    php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
    php > while(list($key,$val) = each($arr)){
              echo "【 $key: $val 】";
          }
    【 0: 12 】【 a: 8 】【 6: 10 】【 b: 3 】【 7: 80 】
    

    注意:由于 list 方法的不确定性,不建议使用该方法遍历数组,了解一下即可。

    4、三种遍历方式的区别

    • for循环只能遍历索引数组
    • foreach可以遍历索引和关联数组
    • while、list()、each()组合循环同样可以遍历索引和关联数组
    • while、list()、each()组合不会reset()
    • foreach遍历会对数组进行reset()操作

    5、for, next(), key(), current()组合

    也是了解即可。

    php > $arr = array( 12, 'a'=>8, 6=>10, 'b'=> 3, 80);
    php > $count = count($arr);
    php > for($i=0; $i<$count;$i++){
              $key = key($arr);
              $val = current($arr);
              echo "$key: $val ==\n";
              next($arr);
          }
    0: 12 ==
    a: 8 ==
    6: 10 ==
    b: 3 ==
    7: 80 ==
    
    //注意,当循环结束后如果再去获取key和val,将不会成功,如:
    $key = key($arr);
    $val = current($arr);
    var_dump($key,$val);   //结果为:NILL、bool(false)
    

    七、常用函数

    1、对数组进行排序

    函数名称 排序依据 索引键保持 排序的顺序 说明
    array_multisort 键值关联(string)的保持,数字类型的不保持 第一个数组或者由选项指定 对多个数组或多维数组进行排序
    sort 由低到高 对数组从最低到最高重新排序
    rsort 由高到低
    asort 由低到高
    arsort 由高到低 对数组进行逆向排序并保持索引关系
    natsort 自然排序
    natcasesort 自然排序,大小写不敏感
    ksort 由低到高
    krsort 由高到低
    usort 由用户定义
    uasort 由用户定义
    uksort 由用户定义
    shuffle 打乱数组 此函数会为数组中的元素赋与新的键名,这将删除原有的键名

    注意:
    以上的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。

    使用 array_multisort 对多维数组或多个数组排序,原理类似于SQL语句中Order By 的多字段排序。但是提供给array_multisort 的多个数组数组和之前的数组要有相同数量的元素。

    例:

    // 多个数组排序
    php > $ar1 = array(10, 100, 100, 0,100);
    php > $ar2 = array(1, 5, 2, 4, 3);  # 和第一个数组一样拥有5个元素
    php > array_multisort($ar1, $ar2);
    php >
    php > print_r($ar1);
    Array
    (
        [0] => 0
        [1] => 10
        [2] => 100
        [3] => 100
        [4] => 100
    )
    php > print_r($ar2);
    Array
    (
        [0] => 4
        [1] => 1
        [2] => 2
        [3] => 3
        [4] => 5
    )
    

    2、数组与字符串间的转换

    函数 说明
    implode 将一个一维数组的值转化为字符串。别名:join
    explode 使用一个字符串分割另一个字符串,返回数组
    split 用正则表达式将字符串分割到数组中
    preg_split 通过一个正则表达式分隔字符串,返回数组。通常是比 split() 更快的替代方案
    str_split 根据每一段的长度,将字符串转换为数组
    php > $str ="hypertext language, programming";
    php > $keywords = preg_split("/[\s,]+/", $str);
    php > print_r($keywords);
    Array
    (
        [0] => hypertext
        [1] => language
        [2] => programming
    )
    

    3、数组的运算

    函数 说明
    array_unique 移除数组中重复的值。返回过滤后的数组
    array_merge 合并一个或多个数组。返回合并后的结果数组。
    array_merge_recursive 递归地合并一个或多个数组
    array_intersect 计算数组的交集
    array_intersect_assoc 带索引检查计算数组的交集
    array_diff 计算数组的差集
    array_diff_assoc 带索引检查计算数组的差集
    array_push 将一个或多个单元压入数组的末尾(入栈)。返回处理之后数组的元素个数。
    array_pop 弹出数组最后一个单元(出栈)。返回 array 的最后一个值
    array_pad 以指定长度将一个值填充进数组
    array_shift 将 array 的第一个单元移出并作为结果返回
    array_unshift 将传入的单元插入到 array 数组的开头
    array_replace 使用传递的数组替换第一个数组的元素
    array_replace_recursive 使用传递的数组递归替换第一个数组的元素
    list 把数组中的值赋给一组变量
    像 array() 一样,list()不是真正的函数,而是语言结构。

    1)— 合并一个或多个数组——array_merge。该函数与数组解包运算符(...)原理一样。
    array_merge() 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
    如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
    如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引

    $array1 = array("color" => "red", 2, 4);
    $array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
    $result = array_merge($array1, $array2);
    print_r($result);
    
    //以上例程会输出:
    Array
    (
        [color] => green
        [0] => 2
        [1] => 4
        [2] => a
        [3] => b
        [shape] => trapezoid
        [4] => 4
    )
    

    注意:
    PHP 7.4.0+ 允许不带参数调用,之前版本至少需要一个参数。
    如果你想完全保留原有数组并只想新的数组附加到后面,则可用 + 运算符。

    2)计算数组的交集 — array_intersect
    array array_intersect ( array $array1 , array $array2 [, array $... ] )
    返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

    $array1 = array("a" => "green", "red", "blue");
    $array2 = array("b" => "green", "yellow", "red");
    $result = array_intersect($array1, $array2);
    print_r($result);
    // 以上例程会输出:
    Array
    (
        [a] => green
        [0] => red
    )
    

    3)计算数组的差集 — array_diff
    array array_diff ( array $array1 , array $array2 [, array $... ] )
    返回一个数组,该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意键名保留不变。

    如果需要得出简单差集,可以通过如下方法:

    $difference = array_merge(array_diff($a, $b), array_diff($b, $a));
    

    4)入栈 array_push 与 出栈 array_pop

    array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和$array[] = $var;效果相同。
    Note: 如果用 array_push() 来给数组增加一个单元,还不如用 $array[] = ,因为这样没有调用函数的额外负担。
    Note: 如果第一个参数不是数组,array_push() 将发出一条警告。这和 $var[] 的行为不同,后者会新建一个数组。

    array_pop() 弹出并返回 array 数组的最后一个单元,并将数组 array 的长度减一。

    5)array_pad — 以指定长度将一个值填充进数组
    array array_pad ( array $array , int $size , mixed $value )
    函数array_pad 返回 array 的一个拷贝,并用 value 将其填补到 size 指定的长度。如果 size 为正,则填补到数组的右侧,如果为负则从左侧开始填补。如果 size 的绝对值小于或等于 array 数组的长度则没有任何填补。有可能一次最多填补 1048576 个单元。

    $input = array(12, 10, 9);
    
    $result = array_pad($input, 5, 0);
    // result is array(12, 10, 9, 0, 0)
    

    4、数组的键与值

    函数 说明
    array_count_values 统计数组中所有的值。返回一个数组:
    数组的键是 array 里单元的值; 数组的值是 array 单元的值出现的次数
    count 计算数组中的单元数目,或对象中的属性个数
    array_values 返回数组中所有的值,并给其建立数字索引。
    array_keys 返回数组中部分的或所有的键名
    array_key_exists 检查数组里是否有指定的键名或索引
    in_array 检查数组中是否存在某个值
    array_search 在数组中搜索给定的值,如果成功则返回首个相应的键名

    例1:返回数组中所有的值并给其建立数字索引

    $array = array("size" => "XL", "color" => "gold");
    print_r(array_values($array));
    //上例会输出:
    Array
    (
        [0] => XL
        [1] => gold
    )
    

    例2:返回数组中部分的或所有的键名
    array array_keys ( array $array [, mixed $search_value = null [, bool $strict = false ]] )
    如果指定了可选参数 search_value,则只返回该值的键名。否则 input 数组中的所有键名都会被返回。

    $array = array(0 => 100, "color" => "red");
    print_r(array_keys($array));
    
    $array = array("blue", "red", "green", "blue", "blue");
    print_r(array_keys($array, "blue"));
    
    // 以上例程会输出:
    Array
    (
        [0] => 0
        [1] => color
    )
    Array
    (
        [0] => 0
        [1] => 3
        [2] => 4
    )
    

    例3:在数组中搜索给定的值,如果成功则返回首个相应的键名**
    mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
    大海捞针,在大海(haystack)中搜索针( needle 参数)。
    如果 needlehaystack 中出现不止一次,则返回第一个匹配的键。要返回所有匹配值的键,应该用 array_keys() 加上可选参数 search_value 来代替。

    $array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
    $key = array_search('green', $array);   // $key = 2;
    

    例4:检查数组里是否有指定的键名或索引**
    bool array_key_exists ( mixed $key , array $array )
    array_key_exists() 仅仅搜索第一维的键。 多维数组里嵌套的键不会被搜索到。

    $search_array = array('first' => 1, 'second' => 4);
    if (array_key_exists('first', $search_array)) {
        echo "The 'first' element is in the array";
    }
    

    5、数组生成器

    函数 说明
    array_fill 用给定的值填充数组。生成数组
    array_fill_keys 使用指定的键和值填充数组
    range 根据范围创建数组,包含指定的元素
    array_combine 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值

    例:

    php > $a = array_fill(2, 5, 'banana');
    php > print_r($a);
    Array
    (
        [2] => banana
        [3] => banana
        [4] => banana
        [5] => banana
        [6] => banana
    )
    
    php > $b = range(10, 100, 20);
    php > print_r($b);
    Array
    (
        [0] => 10
        [1] => 30
        [2] => 50
        [3] => 70
        [4] => 90
    )
    
    php > $c = array_combine($b,$a);
    php > print_r($c);
    Array
    (
        [10] => banana
        [30] => banana
        [50] => banana
        [70] => banana
        [90] => banana
    )
    

    6、回调函数的应用

    函数 说明
    array_map 为数组的每个元素应用回调函数
    array_filter 用回调函数过滤数组中的单元
    array_walk 使用用户自定义函数对数组中的每个元素做回调处理
    array_walk_recursive 对数组中的每个成员递归地应用用户函数。
    array_reduce 用回调函数迭代地将数组简化为单一的值

    例1:array_map — 为数组的每个元素应用回调函数
    array array_map ( callable $callback , array $array1 [, array $... ] )
    array_map():返回数组,是为 array 每个元素应用 callback函数之后的数组。 array_map() 返回一个 array,数组内容为 array1 的元素按索引顺序为参数调用 callback 后的结果(有更多数组时,还会传入 arrays 的元素)。 callback 函数形参的数量必须匹配 array_map() 实参中数组的数量。

    function cube($n) {
        return ($n * $n * $n);
    }
    $a = array(1, 2, 3, 4, 5);
    $b = array_map("cube", $a);
    print_r($b);
    
    //结果如下:
    Array
    (
        [0] => 1
        [1] => 8
        [2] => 27
        [3] => 64
        [4] => 125
    )
    

    注意:传入两个及以上的数组时,它们元素数量将会相同。因为回调函数会并行地处理相互对应的元素。 如果几个数组的元素数量不一致:空元素会扩展短那个数组,直到长度和最长的数组一样。

    function show_Spanish($n, $m) {
        return "The number {$n} is called {$m} in Spanish";
    }
    $a = [1, 2, 3, 4, 5];
    $b = ['uno', 'dos', 'tres', 'cuatro'];
    
    $c = array_map('show_Spanish', $a, $b);
    print_r($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  in Spanish
    )
    

    例2:array_filter — 用回调函数过滤数组中的单元
    array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )
    依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

    如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。

    function odd($var) {
        return($var & 1);   // 奇数会返回1,偶数会返回0
    }
    function even($var) {
        return(!($var & 1));
    }
    
    $array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
    $array2 = array(6, 7, 8, 9, 10);
    
    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
    )
    

    callback 函数对于想保留的值返回true,对于不想保留的值返回false。

    例3:array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
    bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] )
    成功时返回 TRUE, 或者在失败时返回 FALSE。
    Note: 如果 callback 需要直接作用于数组中的值,则给 callback 的第一个参数指定为引用。这样任何对这些单元的改变也将会改变原始数组本身。

    $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');
    ?>  
    
    // 以上例程会输出:
    Before ...:
    d. lemon
    a. orange
    b. banana
    c. apple
    ... and after:
    d. fruit: lemon
    a. fruit: orange
    b. fruit: banana
    c. fruit: apple
    

    注意:
    array_walk_recursive() — 对数组中的每个成员递归地应用用户函数。array_walk_recursive函数只将非数组元素传递到回调函数,所以从array_walk切换时不需要修改回调。

    八、经典实例

    1、根据父ID获取所有下级的子ID(子ID下面上可能还有子ID))

    //测试数据
    $data = [
            0=>['id'=>1,'name'=>'zhuangsan','pid'=>4],
            1=>['id'=>2,'name'=>'zhuangsan','pid'=>3],
            2=>['id'=>3,'name'=>'zhuangsan','pid'=>4],
            3=>['id'=>4,'name'=>'zhuangsan','pid'=>6],
            4=>['id'=>5,'name'=>'zhuangsan','pid'=>2],
            5=>['id'=>6,'name'=>'zhuangsan','pid'=>9]
    ];
    
    /**
     * 递归获取所有子id
     * @param $data 数据集
     * @param $pid 父id
     */
    function select_tree($data,$pid){
        static $treeid = array();
        foreach($data as $key=>$val){
            if($pid==$val['pid']){
                $treeid[] = $val['id'];
                select_tree($data,$val['id']);
            }     
        }
        return $treeid;
    }
    
    $res = select_tree($data,4);
    var_dump($res); 
    
    //运行结果:
    root@Chan:~$ php demo11.php
    array(4) {
      [0] =>
      int(1)
      [1] =>
      int(3)
      [2] =>
      int(2)
      [3] =>
      int(5)
    }
    

    注意: 此类型题数据中不允许出现层级循环,否则该递归方法将出现死循环,程序报错!
    扩展: 要求不使用递归,写出一个解决上题的方法。

    2、写一个函数,要求不使用array_merge完成多个数组的合并

    $arr1 = ['2'=>'no',5=>100,3];
    $arr2 = [1,2,3];
    $arr3 = [1=>'a','b','c'];
    function array_mer(){
            $return = [];
            $arrays = func_get_args();
            foreach($arrays as $arr){
                    foreach($arr as $v){
                            $return[] = $v;
                    }
            }
            return $return;
    }
    $arr = array_mer($arr1,$arr2,$arr3);
    var_dump($arr);
    

    结果如下(与array_merge函数返回的结果一样):

    array (size=9)
      0 => string 'no' (length=2)
      1 => int 100
      2 => int 3
      3 => int 1
      4 => int 2
      5 => int 3
      6 => string 'a' (length=1)
      7 => string 'b' (length=1)
      8 => string 'c' (length=1)
    

    九、参考:

    1、官方文档:

    2、相关书籍:

    • 《PHP经典实例》 David Sklar & Adam Trachtenb

    相关文章

      网友评论

          本文标题:PHP强化之03 - 数组 Array(新)

          本文链接:https://www.haomeiwen.com/subject/zyspcrtx.html