PHP数据类型之array

80
0
0
2024-05-12 13:45
最后编辑于2024-05-19 15:06

今天说说PHP8中的数组,数组是非常强大的存在,可以说无处不用,从数据库读取出来的单行和多行,返回结果都是数组,虽然PHP框架中都有ORM的封装,使得返回是对象,但偶偶也会用到原生数组的返回,在配置文件中,大都也是用数组,像复杂的框架Symfony,它的配置文件可以为yaml,xml,php三种,yaml和xml都可以轻易的转为数组来处理,先说说数组的定义以及输出:

$arr1 = array(1, 2, 4); //正常形式
$arr2 = ['a'=>1, 2, 4]; //简写形式,一般都用这种
$arr3 = [
    'a' => [1, 6],
    '55',
    '1.2' => 55,//需要用字符串,否则会报 Deprecated 错误。
    false => 44,//false自动转为0, 如果数组中已有下标0的,则会被覆盖
    -1 => 3333,
];

$arr1[] = 5;//数字下标的赋值
$arr2['b'] = 5;//字母下标赋值
$arr3[1+2] = 666;//下标可以运算,也可以用函数或方法

//输出数组,带类型
var_dump($arr1);

//输出数组,可读性高,一般用这种
print_r($arr2);

//输出数组,格式化,一般用于写入php文件(第2个参数设为true)
var_export($arr3) . "\n";

var_dump($arr1[0]);
print_r($arr3['a']);

数组的判断用is_array方法,简单又方便,下面说说数组的关键部分,就是循环,数组的遍历有很多种方式,常用的有,foreach,for,while,foreach应该是用的最多的一种,下面分别详细举例说明:

foreach (['a'=>1, 'b'=>2, 'c'=>3] as $key=>$value) {
    echo (sprintf("%s: %d\n", $key, $value));
}

$arr4 = ['a', 'd', 'f'];
for ($i=0; $i<count($arr4); $i++) {
    echo (sprintf("%d: %s\n", $i, $arr4[$i]));
}

$arr5 = [
    'a' => 'a1',
    'b' => 'b1',
    'c' => 'c1',
    'd' => 'd1',
];
while (true) {
    $value = current($arr5);
    $key = key($arr5);
    echo (sprintf("%s: %s\n", $key, $value));
    $value = next($arr5);
    $key = key($arr5);
    if ($value === false && $key === null) {
        break;
    }
}

上面这些是比较简单的循环遍历,下面说几个稍微复杂一点的,这些在遍历数组对象时特别有用,这几个在实际项目开发中,用的非常之多,也需要掌握的,看以下例子:

class ArrObj1
{
    public function __construct(protected string $a) {}

    public function getA(): string
    {
        return $this->a;
    }
}
$arr6 = [];
$arr6[] = new ArrObj1('a');
$arr6[] = new ArrObj1('b');
$arr6[] = new ArrObj1('c');

//单纯的遍历,如果有额外参数可以用use
array_walk($arr6, function (ArrObj1 $arrObj1, int $key) use ($arr5) {
    echo sprintf("%d: %s\n", $key, $arrObj1->getA());
}, ARRAY_FILTER_USE_BOTH);

//遍历,遍历的返回值会改变数组本身,如果有额外参数可以用use
print_r(array_map(function (ArrObj1 $arrObj1)  use ($arr5) {
    echo sprintf("%s\n", $arrObj1->getA());
    return $arrObj1->getA() . $arrObj1->getA();
}, $arr6));//输出 ['aa', 'bb', 'cc']

//遍历,根据遍历的结果false/true来过滤掉数组内元素,如果有额外参数可以用use
print_r(array_filter($arr6, function (ArrObj1 $arrObj1, int $key)  use ($arr5) {
    echo sprintf("%d: %s\n", $key, $arrObj1->getA());
    return $arrObj1->getA() != 'b';
}, ARRAY_FILTER_USE_BOTH));//输出 [object('a'), object('b')]

each方法的遍历已经被Deprecated,请大家不要再用。

下面说说数组的几个排序函数,偶偶也会用到,需要了解一下。

//基础排序
$arr7 = ['a'=>1, 'b'=>8, 'c'=>5, 'd'=>2];
//按值顺序排序
sort($arr7);
print_r($arr7);//输出 [1, 2, 5, 8]  会丢失key

$arr8 = ['a'=>1, 'b'=>8, 'c'=>5, 'd'=>2];
//按值逆向排序
rsort($arr8);
print_r($arr8);//输出 [8, 5, 2, 1]  会丢失key

$arr9 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
//按值对数组排序, 并保留key
asort($arr9);
print_r($arr9);//输出 ['a'=>1, 'd'=>2, 'c'=>5, 'b'=>8,]

$arr10 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
//按值对数组排序, 并保留key
arsort($arr10);
print_r($arr10);//输出 ['b'=>8, 'c'=>5, 'd'=>2, 'a'=>1,]

$arr11 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
//按key对数组排序
ksort($arr11);
print_r($arr11);//输出 ['a'=>1, 'b'=>8,  'c'=>5, 'd'=>2,]

上面几个是比较简单的排序,如果不能满足业务需求,可以试试自定义排序:

//自定义排序
$arr12 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
usort($arr12, function (int $v1, int $v2) {
    return intval($v1 > $v2);
});
print_r($arr12);//输出 [1, 2, 5, 8]  会丢失key

$arr13 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
uasort($arr13, function (int $v1, int $v2) {
    return intval($v1 < $v2);
});
print_r($arr13);//输出 [8, 5, 2, 1]  会丢失key

$arr14 = ['a'=>1,  'c'=>5, 'd'=>2, 'b'=>8,];
uksort($arr14, function (string $k1, string $k2) use($arr14) {
    return intval($arr14[$k1] > $arr14[$k2]);
});
print_r($arr14);//输出 ['a'=>1, 'd'=>2, 'c'=>5, 'b'=>8,]

对多维数组进行排序的话,就用到方法array_multisort

$arr15 = [
    [
        'a'=>5,
        'b'=>2,
        'c'=>7
    ],
    [
        'a'=>8,
        'b'=>4,
        'c'=>1
    ],
    [
    'a'=>5,
    'b'=>9,
    'c'=>2
    ],
];
//先按字段a排序,之后字段b排序
array_multisort(array_column($arr15, 'a'), SORT_ASC, array_column($arr15, 'b'), SORT_ASC, $arr15);
print_r($arr15); //结果如下:
//Array
//(
//    [0] => Array
//    (
//        [a] => 5
//        [b] => 2
//        [c] => 7
//    )
//
//    [1] => Array
//    (
//        [a] => 5
//        [b] => 9
//        [c] => 2
//    )
//
//    [2] => Array
//    (
//        [a] => 8
//        [b] => 4
//        [c] => 1
//    )
//)

其它的数组的常用函数如下:

//常用数组函数
$arr16 = [
    [
        'a'=>1,
        'b'=>2,
        'c'=>3
    ],
    [
        'a'=>4,
        'b'=>5,
        'c'=>6
    ]
];
//这个在数据库中读取某一列时很好用
print_r(array_column($arr16, 'a'));//输出 [1, 4]

//key和value对应组合成一个数组
print_r(array_combine(['a', 'b', 'c'], [1, 2, 3]));//输出 ['a'=>1, 'b]=>2, 'c'=>3]

$arr17 = ['a'=>1, 'b'=>2, 'c'=>3];
//交换key和value
print_r(array_flip($arr17));//输出 [1=>'a', 2=>'b', 3=>'c']

$arr18 = ['a'=>1, 'b'=>2, 'c'=>3];
//翻转数组
print_r(array_reverse($arr18));//输出 ['c'=>3, 'b'=>2, 'a'=>1]

//获取数组数量
echo count([1, 8, 4]) . "\n";//输出 3

//判断某个值是否在数组中,区别大小写的,要不区分,需传入第3个参数true
var_dump(in_array('a', ['c', 'b', 'a']));//输出 true

//判断某个key是否在数组中
var_dump(array_key_exists('a', ['c'=>3, 'b'=>2, 'a'=>1]));

//获取数组中的第一个key
var_dump(array_key_first(['c'=>3, 'b'=>2, 'a'=>1]));//输出 c

//获取数组中的最后一个key
var_dump(array_key_last(['c'=>3, 'b'=>2, 'a'=>1]));//输出 a

//获取数组中所有key
print_r(array_keys(['c'=>3, 'b'=>2, 'a'=>1]));//输出 ['c', 'b', 'a']

//获取数组中所有value
print_r(array_values(['c'=>3, 'b'=>2, 'a'=>1]));//输出 [3, 2, 1]

//将数组指针重置到开始
//reset();

//将数组指针移动到结尾
//end();

//获取当前数组的值
//current();

//将数组指针移动到下一个
//next();

//取差集, 在第一个数组中去除在第二个数组存在的相同值
$arr18 = ['a'=>1, 'b'=>3, 'c'=> 6];
$arr19 = ['a'=>1, 't'=>8, 'c'=> 9];
print_r(array_diff($arr18, $arr19));//输出 ['b'=>3, 'c'=>6]

//用key取差集, 在第一个数组中去除在第二个数组存在的相同key的value
$arr20 = ['a'=>1, 'b'=>3, 'c'=> 6];
$arr21 = ['a'=>1, 't'=>8, 'c'=> 9];
print_r(array_diff_key($arr20, $arr21));//输出 ['b'=>3]

//取交集, 在第一个数组中存在并在第二个数组也存在的相同值
$arr22 = ['a'=>1, 'b'=>3, 'c'=> 6];
$arr23 = ['a'=>1, 't'=>8, 'c'=> 9];
print_r(array_intersect($arr22, $arr23));//输出 ['a'=>1]

//用key取交集, 在第一个数组中存在并在第二个数组也存在的相同key的value
$arr24 = ['a'=>1, 'b'=>3, 'c'=> 6];
$arr25 = ['a'=>1, 't'=>8, 'c'=> 9];
print_r(array_intersect_key($arr24, $arr25));//输出 ['a'=>1, 'c'=>6]

//将一个或多个值放入数组尾部
$arr26 = ['a'=>1];
array_push($arr26, 2, 3);
print_r($arr26);//输出 ['a'=>1, 2, 3]

//从数组尾部取出一个值,如果数组为空,返回null
$arr27 = ['a'=>1, 'b'=>2, 'c'=>3];
print_r(array_pop($arr27));//输出 3

//将一个或多个值放入数组头部
$arr28 = ['a'=>1];
array_unshift($arr28, 2, 3);
print_r($arr28);//输出 [2, 3, 'a'=>1]

//从数组头部取出一个值,如果数组为空,返回null
$arr29 = ['a'=>1, 'b'=>2, 'c'=>3];
var_dump(array_shift($arr29));//输出 1

//取出数组中的随机key
$arr30 = ['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4];
var_dump(array_rand($arr30));//输出 a, b, c, d中的随机一个

//将数组随机打乱,注意key会丢失
$arr31 = ['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4];
shuffle($arr31);
print_r($arr31);//输出 打乱后的数组

//将两个或多个数组merge,数字key会被重新编号,一定要注意
$arr32 = ['a'=>1, 1=>1, 2=>2];
$arr33 = ['a'=>2, 3=>3];
print_r(array_merge($arr32, $arr33));//输出 ['a'=>2, 0=>1, 1=>2, 2=>3]

//搜索数组的值,并返回key
var_dump(array_search(2, ['a'=>1,'b'=>2,'c'=>3]));//输出 b

//将数组中的值求和,有字符串将被自动转化
var_dump(array_sum([1,4,5,'6b']));//输出 16

//取出数组中的某一段
print_r(array_slice([1,2,3,4], 0, 2));//输出 [1,2]

//将数组中的值取唯一处理
print_r(array_unique([1, 3, 1, 3]));//输出 [1, 3]

代码放在: https://github.com/leo-up/php-study/blob/master/base/array.php

博主信息
博客数
121
昵称
性别
年龄
39
居住城市
上海市