数组相关函数
1. 与键相关的函数
1.1. array_keys(待处理数组, 只返回值等于本参数值的键值对的键名[可选], 是否严格比较[可选]): 返回数组中的所有(默认情况)或部分键名形成的数组
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
// 1. 常规用法, 返回所有键名
$keys = array_keys($arr);
printfpre($keys);
/*
result:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => id
[5] => name
[6] => age
[7] => salary
[8] => in_use
[9] => roles
)
*/
// 2. 只返回键值对的值为某值的键名
/* demo1: 非严格比较, '33' == 33 */
$value = '33';
$keys = array_keys($arr, $value);
printfpre($keys);
/*
result:
Array
(
[0] => age
[1] => in_use
)
*/
/* demo2: 严格比较, '33' !== 33 */
$keys = array_keys($arr, $value, true);
printfpre($keys);
/*
result:
Array
(
)
*/
$value = 33;
$keys = array_keys($arr, $value, true);
printfpre($keys);
/*
Array
(
[0] => age
)
*/
1.2. array_key_exists(目标键名, 待处理数组): 是否存在指定键名
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
$targetKey = 'name';
echobr(array_key_exists($targetKey, $arr) ? '存在' : '不存在');
/*
result: 存在
*/
1.3. array_key_first(待处理数组): 要求PHP7.3+, 获取第一个键值对的键名
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
echobr(array_key_first($arr));
/*
result: 0
*/
1.4. array_key_last(待处理数组): 要求PHP7.3+, 获取最后一个键值对的键名
echobr(array_key_last($arr));
/*
result: roles
*/
2. 与数组元素值相关的函数
2.1. array_values(待处理数组): 返回数组中所有值组成的数组
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
printfpre(array_values($arr));
/*
result:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 1
[6] => admin
[7] => 33
[8] => 9999
[9] => 1
[10] => Array
(
[0] => 1
[1] => 2
[2] => 34
[3] => 5
[4] => 6
)
)
*/
2.2. in_array(目标值, 待处理数组, 是否严格比较[可选]): 检查数组中是否存在某个值
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
$targetValue = '33';
echobr((in_array($targetValue, $arr) ? '存在' : '不存在'));
/*
默认为不严格比较, '33' == 33
result: 存在
*/
echobr(in_array($targetValue, $arr, true) ? '存在' : '不存在');
/*
使用严格比较, '33' !== 33
result: 不存在
*/
2.3. array_search(待搜索的目标值, 待处理数组, 是否严格比较[可选]): 搜索指定值, 返回(匹配到的第一个)键名
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
$targetValue = '33';
dumpbr(array_search($targetValue, $arr));
/*
不使用严格模式, '33' == 33
result: string(3) "age" */
dumpbr(array_search($targetValue, $arr, true));
/*
严格模式, '33' !== 33, 返回false
result: bool(false)
*/
2.4. array_unique(待处理的数组, 排序策略[可选]): 移除数组中重复的值.
- 删除策略: 先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。这并不意味着在未排序的 array 中同一个值的第一个出现的键名会被保留。
- 排序策略:
- SORT_REGULAR - 按照通常方法比较(不修改类型)
- SORT_NUMERIC - 按照数字形式比较
- SORT_STRING - 按照字符串形式比较
- SORT_LOCALE_STRING - 根据当前的本地化设置,按照字符串比较。
printfpre(array_unique($arr));
/*
'id'被删除了
result:
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[name] => admin
[age] => 33
[salary] => 9999
[roles] => Array
(
[0] => 1
[1] => 2
[2] => 34
[3] => 5
[4] => 6
)
)
*/
3. 与统计相关的数组函数
3.1. count(待处理数组, 计算模式[可选]): 计算数组中元素的数量, 或对象中的属性数量.
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 34, 5, 6],
];
echobr(count($arr));
/*
不包括roles值中数组元素的个数
result: 11
*/
echobr(count($arr, COUNT_RECURSIVE));
/*
包括二维数组(roles值中数组元素的个数)
result: 16
*/
3.2. array_count_values(待处理数组): 计算数组值在数组中出现的次数(只能统计值类型为字符串或数字的出现频率)
printfpre(array_count_values($arr));
/*
key=原数组值; value=原数组值在原数组中出现的次数; roles的值不能统计
result:
Warning: array_count_values(): Can only count STRING and INTEGER values! in D:\phpstudy_pro\WWW\php11\PHP\0424\homework.php on line 253
Array
(
[0] => 1
[1] => 2
[2] => 1
[3] => 1
[4] => 1
[admin] => 1
[33] => 1
[9999] => 1
)
*/
4. 与计算有关
4.1. array_sum(待处理数组): 对数组中所有值求和
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
// 'name' => 'admin',
'age' => '33',
'salary' => 5000,
'in_use' => true,
'roles' => 1, //[1, 2, 34, 5, 6],
'key1' => '100php123',
// 'key2' => 'php100',
];
echobr(array_sum($arr));
/*
会自动跳过非数字值(数字字符串也被视为数字值, true = 1, false = 0), 数组也被忽略, 以数字开头的字符串, 会解析开头的数字部分(100php123=>100)
result: 5145
*/
4.2. array_product(待处理数组): 计算数组中所有值的乘积
- 会自动解析数字值(数字字符串也被视为数字值, true = 1, false = 0), 数组 = 1, 以数字开头的字符串, 会解析开头的数字部分; 其他(以非数字开始的字符串等) = 0
echobr(array_product($arr));
/*
result: 0 */
5. 栈与队列
5.1 array_push(待处理数组, 入栈值1, 入栈值2…[可选]): 将一个或多个元素压入数组的末尾(入栈)
$arr = [];
$count = array_push($arr, 1, 2, 3, 4, 5, 6, 7, 8);
echobr('共' . $count . '个元素入栈');
dumpbr($arr);
/*
result:
共8个元素入栈
array(8) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) [7]=> int(8) }
*/
5.2 array_pop(待处理数组): 弹出并返回待处理数组的最后一个元素(出栈)
$lastValue = array_pop($arr);
echobr('最后一个元素的值是: ' . $lastValue);
/* result: 最后一个元素的值是: 8 */
5.3 array_unshift(待处理数组, 添加值1, 添加值2…[可选]): 从待处理数组头部添加一个或多个元素
$count = array_unshift($arr, 'a', 'b', 'c', 'd');
echobr('共在头部添加' . $count . '个元素');
dumpbr($arr);
/* result:
共在头部添加11个元素
array(11) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> int(1) [5]=> int(2) [6]=> int(3) [7]=> int(4) [8]=> int(5) [9]=> int(6) [10]=> int(7) } */
5.4 array_shift(待处理数组): 从头部删除一个元素, 并返回被删除的元素
$delValue = array_shift($arr);
echobr('被删除的数组元素值是: ' . $delValue);
/*
result: 被删除的数组元素值是: a
*/
6. 排序
6.1 对值排序
- sort(待处理数组, 排序策略[可选]): 按值升序排序, 索引重排;
- asort(待处理数组, 排序策略[可选]): 按值升序排序, 索引保持不变;
- rsort(待处理数组, 排序策略[可选]): 按值降序排序, 索引重排;
- arsort(待处理数组, 排序策略[可选]): 按值降序排序, 索引保持不变;
- 排序策略:
- SORT_REGULAR - 正常比较单元(不改变类型)
- SORT_NUMERIC - 单元被作为数字来比较
- SORT_STRING - 单元被作为字符串来比较
- SORT_LOCALE_STRING - 根据当前的区域(locale)设置来把单元当作字符串比较,可以用 setlocale() 来改变。
- SORT_NATURAL - 和 natsort() 类似对每个单元以“自然的顺序”对字符串进行排序。 PHP 5.4.0 中新增的。
- SORT_FLAG_CASE - 能够与 SORT_STRING 或 SORT_NATURAL 合并(OR 位运算),不区分大小写排序字符串。
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'height' => '174cm',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 5, 34, 6],
];
// demo1: 升序, 键名重排
if (sort($arr)) {
echobr('排序成功');
printfpre($arr);
/*
默认排序策略: 字母开头的字符串被解析为0; 数字开头的字符串, 开头的数字部分被解析为数字; boolean值比所有数字大; 数组值比Boolean值大;
注意: 键值已经重排了
result:
Array
(
[0] => admin
[1] => 0
[2] => 1
[3] => 1
[4] => 2
[5] => 3
[6] => 4
[7] => 33
[8] => 174cm
[9] => 9999
[10] => 1
[11] => Array
(
[0] => 1
[1] => 2
[2] => 5
[3] => 34
[4] => 6
)
)
*/
} else {
echobr('排序失败');
}
// demo2: 升序, 键名保持不变
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'height' => '174cm',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 5, 34, 6],
];
if (asort($arr)) {
echobr('排序成功');
printfpre($arr);
/*
result:
Array
(
[name] => admin
[0] => 0
[1] => 1
[id] => 1
[2] => 2
[3] => 3
[4] => 4
[age] => 33
[height] => 174cm
[salary] => 9999
[in_use] => 1
[roles] => Array
(
[0] => 1
[1] => 2
[2] => 5
[3] => 34
[4] => 6
)
) */
} else {
echobr('排序失败');
}
// 排序策略测试略.
// rsort()和arsort()使用方法类似, 略.
6.2 对键排序
- ksort(待处理数组, 排序策略[可选]): 按键名升序排序
- krsort(待处理数组, 排序策略[可选]): 按键名降序排序
- 排序策略值: 参考6.1
// 1. 键名升序
$arr = [
0, 1, 2, 3, 4,
'id' => 1,
'name' => 'admin',
'height' => '174cm',
'age' => 33,
'salary' => 9999,
'in_use' => true,
'roles' => [1, 2, 5, 34, 6],
];
if (ksort($arr)) {
echobr('键名升序排序成功');
printfpre($arr);
/*
默认排序策略的解释, 见6.1-demo1
resunt:
Array
(
[age] => 33
[0] => 0
[height] => 174cm
[id] => 1
[in_use] => 1
[name] => admin
[roles] => Array
(
[0] => 1
[1] => 2
[2] => 5
[3] => 34
[4] => 6
)
[salary] => 9999
[1] => 1
[2] => 2
[3] => 3
[4] => 4
)
*/
}
// rksort()使用方法跟ksort()相同, 略.
6.3 自定义排序
- usort(待处理数组, 写有排序逻辑的回调函数): 使用用户自定义的比较函数对数组中的值进行排序
- uasort(待处理数组, 写有排序逻辑的回调函数): 使用用户自定义的比较函数对数组中的值进行排序, 并保持索引不变
// 回调函数说明:
function (数组中的值1, 数组中的值2) {
/*在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数。*/
}
/* demo1: 模拟升序排列, 键名重排 */
$arr = [
'key1' => 10, 'key2' => 1, 'key3' => 21, 'key4' => 13, 'key5' => 4
];
// 模拟升序排列
usort($arr, function ($val1, $val2) {
return $val1 <=> $val2;
});
printfpre($arr);
/* result: Array
(
[0] => 1
[1] => 4
[2] => 10
[3] => 13
[4] => 21
) */
/* demo2: 模拟降序排列, 键名不重排 */
$arr = [
'key1' => 10, 'key2' => 1, 'key3' => 21, 'key4' => 13, 'key5' => 4
];
// 模拟降序排列, 键名保持不变
uasort($arr, function ($val1, $val2) {
return $val2 <=> $val1;
});
printfpre($arr);
/*
result:
Array
(
[key3] => 21
[key4] => 13
[key1] => 10
[key5] => 4
[key2] => 1
)
*/
// - uksort(待处理数组, 写有排序逻辑的回调函数): 自定义函数对键名进行排序. 略
6.3 自然排序
- natsort(待处理字符串): 支持数字型字符串排序
- natcasesort(待处理字符串): 支持数字型字符串排序(不区分大小写的版本)
在字符串中的数字字符串将被当做数字值来排序.
$arr = ['r10c1', 'r1c1', 'r10c3', 'r2c2', 'r1c2', 'r10c2', 'r2c3', 'r2c1', 'r1c3', 'r2c4', 'r1c4', 'r10c4'];
if (natsort($arr)) {
printfpre($arr);
/*
字符串中的'10'将被当做数字10来排序, 而不是字符串从左到右按字符ASCII码排序(sort就是后者)
result:
Array
(
[1] => r1c1
[4] => r1c2
[8] => r1c3
[10] => r1c4
[7] => r2c1
[3] => r2c2
[6] => r2c3
[9] => r2c4
[0] => r10c1
[5] => r10c2
[2] => r10c3
[11] => r10c4
)
*/
}
6.4 乱序反转
- shuffle(待处理数组): 随机打乱数组中元素的顺序
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
if (shuffle($arr)) {
echobr(implode(', ', $arr));
/* result: 5, 4, 2, 1, 8, 10, 3, 7, 6, 9 */
}
// - array_flip(待处理数组): 交换数组中的键和值, 返回交换后的数组
$arr = [
'key1' => 10, 'key2' => 1, 'key3' => 21, 'key4' => 13, 'key5' => 4
];
$res = array_flip($arr);
printfpre($res);
/*
result:
Array
(
[10] => key1
[1] => key2
[21] => key3
[13] => key4
[4] => key5
)
*/
- array_reverse(待处理数组, 是否保留索引数组的键[可选]): 将数组中的元素反向排列. 返回反转后的数组.
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/* demo1: 不保留索引数组的键 */
$res = array_reverse($arr);
printfpre($res);
/* result:
Array
(
[0] => 10
[1] => 9
[2] => 8
[3] => 7
[4] => 6
[5] => 5
[6] => 4
[7] => 3
[8] => 2
[9] => 1
)
*/
/* demo2: 保留索引数组的键 */
printfpre(array_reverse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], true));
/* result:
Array
(
[9] => 10
[8] => 9
[7] => 8
[6] => 7
[5] => 6
[4] => 5
[3] => 4
[2] => 3
[1] => 2
[0] => 1
)
*/
7. 查询与替换
7.1 array_slice(待处理的数组, 开始取元素的起始索引,截取长度[可选], 索引数组是否重排索引[可选]): 从数组中取出部分连续的元素组成新数组
开始截取的索引和截取长度都可以是负数, 截取长度为负数时, 表示从截取的终点索引(从末尾往回数)
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
/* demo1: 从第3个开始截取, 截取4个元素组成数组 */
$res = array_slice($arr, 2, 4);
printfpre($res);
/*
注意: 索引重排了
Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
)
*/
/* demo2: 不指定截取长度, 则表示从截取开始位置开始, 截取到数组末尾 */
$res = array_slice($arr, 9);
printfpre($res);
/*
result:
Array
(
[0] => 10
[1] => 11
[2] => 12
)
*/
/* demo3: 保留原索引 */
$res = array_slice($arr, 2, 4, true);
printfpre($res);
/*
数组索引还是元素在原数组中的索引
Array
(
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
*/
/* demo4: 使用负数值1-从倒数第5个元素开始截取, 截取3个元素, 组成新数组 */
$res = array_slice($arr, -5, 3);
printfpre($res);
/*
result:
Array
(
[0] => 8
[1] => 9
[2] => 10
)
*/
/* demo5: 使用负数值2-从倒数第5哥元素开始截取, 截取到倒数第2个, 组成新数组, 保留原数组索引 */
$res = array_slice($arr, -5, -2, true);
printfpre($res);
/*
result:
Array
(
[7] => 8
[8] => 9
[9] => 10
)
*/
7.2 array_splice(待处理数组, 开始取元素的起始索引,截取长度[可选], 用来替换被截取元素的数组[可选]): 删除数组中的一部分并用其他值替代
/* 可以实现对数组元素的:删除,替换/更新,添加 */
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
/* demo1: 删除数组中第3个开始, 共4个元素 */
$del = array_splice($arr, 2, 4);
echobr('被删除的元素:');
echobr(implode(', ', $del));
echobr('删除元素后的原数组:');
echobr(implode(', ', $arr));
/*
result:
被删除的元素:
3, 4, 5, 6
删除元素后的原数组:
1, 2, 7, 8, 9, 10, 11, 12
*/
/* demo2: 不指定截取长度, 表示删除到数组最后一个元素为止 */
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$del = array_splice($arr, 8);
echobr('被删除的元素:');
echobr(implode(', ', $del));
echobr('删除元素后的原数组:');
echobr(implode(', ', $arr));
/*
result:
被删除的元素:
9, 10, 11, 12
删除元素后的原数组:
1, 2, 3, 4, 5, 6, 7, 8
*/
/* demo3: 可以使用负数值表示从数组倒数为止开始截取--截取后替换成新的数组元素值 */
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$newElements = ['a', 'b', 'c', 'd'];
$del = array_splice($arr, -6, 6, $newElements);
echobr('被替换掉的元素:');
echobr(implode(', ', $del));
echobr('替换元素后的原数组:');
echobr(implode(', ', $arr));
/*
result:
被替换掉的元素:
7, 8, 9, 10, 11, 12
替换元素后的原数组:
1, 2, 3, 4, 5, 6, a, b, c, d
*/
/* demo4: 在第5个元素后面插入新的元素(把截取长度设置为0即可) */
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$newElements = ['a', 'b', 'c', 'd'];
array_splice($arr, 5, 0, $newElements);
echobr('插入新元素后的原数组:');
echobr(implode(', ', $arr));
/*
result:
插入新元素后的原数组:
1, 2, 3, 4, 5, a, b, c, d, 6, 7, 8, 9, 10, 11, 12
*/
7.3 array_rand(待处理数组, 取出元素的个数[可选]): 从数组中随机取出一个或多个元素(原数组不受影响)
/* demo1: 随机从数组中取出一个元素 */
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$res = array_rand($arr);
echobr('取出的元素:');
echobr($res);
/* demo2: 随机从数组中取出多个值 */
$res = array_rand($arr, 3);
echobr('取出的元素:');
echobr(implode(', ', $res));
/*
result:
取出的元素:
2, 7, 10
*/
7.4 array_column(待处理数组, 要取出的第二维数组元素的键名或索引值, 指定作为取出的元素值的键名的列名或索引值[可选]): 取出多维数组中的一列, 组成新的数组
说明: 入参2和入参3, 如果待处理的数组是索引数组, 则其值为索引值; 如果待处理数组是关联数组, 则为键名
$arr = [
['id' => 1, 'name' => '张三', 'sex' => 'male', 'age' => 25, 'salary' => 9999],
['id' => 2, 'name' => '李四', 'sex' => 'female', 'age' => 30, 'salary' => 8888],
['id' => 3, 'name' => '王五', 'sex' => 'male', 'age' => 35, 'salary' => 7777],
['id' => 4, 'name' => '赵六', 'sex' => 'male', 'age' => 40, 'salary' => 11111],
['id' => 5, 'name' => '钱七', 'sex' => 'female', 'age' => 45, 'salary' => 9797],
['id' => 6, 'name' => '吴八', 'sex' => 'male', 'age' => 28, 'salary' => 7979],
['id' => 7, 'name' => '陈九', 'sex' => 'male', 'age' => 37, 'salary' => 8866],
];
/* demo1: 取出月薪列的内容, 以name列值作为取出内容的键名 */
$res = array_column($arr, 'salary', 'name');
printfpre($res);
/*
result:
Array
(
[张三] => 9999
[李四] => 8888
[王五] => 7777
[赵六] => 11111
[钱七] => 9797
[吴八] => 7979
[陈九] => 8866
)
*/
/* demo2: 取出第4列值, 以第2列为键名(索引数组才有效) */
// $res = array_column($arr, 3, 1);
// printfpre($res);
/* demo3: 取出年龄列内容 */
$res = array_column($arr, 'age');
printfpre($res);
/*
result:
Array
(
[0] => 25
[1] => 30
[2] => 35
[3] => 40
[4] => 45
[5] => 28
[6] => 37
)
*/
7.5 array_replace(待处理数组, 用于替代的元素数组1, 用于替代的元素数组2…[可选]): 使用后面数组的值替换第一个数组的值.
替换规则: 用替换数组中的值, 替换原数组中相同键名的元素的值. 当有多个替换数组, 且这些数组中有相同的键名元素时, 后面数组元素值的会覆盖前面的数组元素值
/* demo: */
$arr = ['one', 'two', 'three', 'four'];
$cover1 = [0 => '1', 4 => '5th'];
$cover2 = [0 => 'first'];
$res = array_replace($arr, $cover1, $cover2);
echobr(implode(', ', $res));
/*
result: first, two, three, four, 5th
*/
// array_replace_recursive() 太复杂了, 略.
7.6 array_intersect(待处理数组, 要被对比的数组1, 要被对比的数组2…[可选]): 以待处理的数组为主值, 对比要对比的数组, 形成交集.
即, 查找出在所有数组中都出现的键值对(值相等就算, 若值相等键名不等, 则以第一个数组的键名为键名)
$arr = ['first' => '1st', 'second' => '2nd', 'third' => '3rd', 'fourth' => '4th', 'fifth' => '5th'];
$intersect1 = ['first' => '1st', 'second' => '第二', 'seventh' => '5th'];
$intersect2 = ['first' => '1st', 'second' => '2nd', 'fourth' => '5th'];
$res = array_intersect($arr, $intersect1, $intersect2);
printfpre($res);
/*
result:
Array
(
[first] => 1st
[fifth] => 5th
)
*/
7.7 array_intersect_assoc(待处理数组, 要被对比的数组1, 要被对比的数组2…[可选]): 以待处理的数组为主值, 对比要对比的数组, 返回交集.
跟array_interrect()用法一样, 只是array_intersect_assoc()不光要值相等, 键名也要相等才算
$res = array_intersect_assoc($arr, $intersect1, $intersect2);
printfpre($res);
/*
5th值的键名不相等, 所以5th并没有在交集中
result:
Array
(
[first] => 1st
)
*/
7.8 array_diff(待处理数组, 要被对比的数组1, 要被对比的数组2…[可选]): 以待处理的数组为主值, 对比要对比的数组, 返回差集
$arr = ['first' => '1st', 'second' => '2nd', 'third' => '3rd', 'fourth' => '4th', 'fifth' => '5th'];
$compare = ['first' => '1st', 'second' => '第二', 'seventh' => '5th'];
$res = array_diff($arr, $compare);
printfpre($res);
/*
result:
Array
(
[second] => 2nd
[third] => 3rd
[fourth] => 4th
)
*/
7.9 array_diff_assoc(): 使用方法和array_diff()相同, 只是在比较时, 不光比较值, 还比较键名. 略.
8. 数组指针
函数名 | 函数功能 |
---|---|
current | 获取当前元素的值 |
key | 获取当前元素的键名 |
next | 将数组中的内部指针向前移动一位 |
prev | 将数组内部指针倒回一位 |
end | 讲数组的内部指针指向最后一个单元 |
reset | 讲数组的内部指针指向第一个单元 |
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// 获取当前数组指针指向的键名和值
echobr('[' . key($arr) . '] => ' . current($arr));
/* result: [0] => 1 */
// 数组指针向后移动3位(即, 指向第四个元素)
next($arr);
next($arr);
next($arr);
echobr('[' . key($arr) . '] => ' . current($arr));
/* result: [3] => 4 */
// 数组指针往回移一位(即, 指向第三个元素)
prev($arr);
echobr('[' . key($arr) . '] => ' . current($arr));
/* result: [2] => 3 */
// 数组指针移到最有一个元素
end($arr);
echobr('[' . key($arr) . '] => ' . current($arr));
/* result: [8] => 9 */
// 数组指针重置(指回第一个元素)
reset($arr);
echobr('[' . key($arr) . '] => ' . current($arr));
/* result: [0] => 1 */
9. 分割与合并
9.1 array_combine(作为键名的数组, 作为值的数组): 创建一个数组, 用第一个数组的值作为其键名, 第二个数组的值作为其值.
$keys = ['name', 'age', 'sex', 'salary'];
$values = ['zhangsan', 32, 'male', 8888];
$res = array_combine($keys, $values);
printfpre($res);
/*
result:
Array
(
[name] => zhangsan
[age] => 32
[sex] => male
[salary] => 8888
)
*/
9.2 array_merge(待处理数组, 待合并数组…[可选]): 将一个或多个数组的元素合并, 后面数组的值附加到第一个数组的后面, 返回合并后的数组.
- 若合并的数组中有同键名的元素, 则以最后一个待合并的数组值为最后值. (本规则只对非数字键名有效, 数字键名哪怕是相同, 也是会追加, 而不是覆盖)
- 只给了一个数组, 且该数组为索引数组, 则其键名会重排
/* demo1: 元素键名不全是索引的数组*/
$arr = ['host' => 'localhost', 'username' => 'root', 'password' => 'root', 'port' => 3306, 'dbname' => 'phpedu', 0 => 'hello'];
$forCombine = ['host' => '127.0.0.1', 'password' => '123456', 0 => 'hi~'];
$res = array_merge($arr, $forCombine);
printfpre($res);
/*
注意: 索引值键名并没有被合并, 而是追加到合并数组中(0 => 'hi~')
result:
Array
(
[host] => 127.0.0.1
[username] => root
[password] => 123456
[port] => 3306
[dbname] => phpedu
[0] => hello
[1] => hi~
)
*/
/* demo2: 索引数组 */
$arr = [1, 2, 8 => 3, 9 => 4, 10 => 11, 11 => 20];
$res = array_merge($arr);
printfpre($res);
/*
数组键名被重排
result:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 11
[5] => 20
)
*/
9.3 array_chunk(待处理数组, 分割的数组元素个数, 是否保持原键名[可选]): 将一个数组分割为多个子数组
$arr = [
['id' => 1, 'name' => '张三', 'sex' => 'male', 'age' => 25, 'salary' => 9999],
['id' => 2, 'name' => '李四', 'sex' => 'female', 'age' => 30, 'salary' => 8888],
['id' => 3, 'name' => '王五', 'sex' => 'male', 'age' => 35, 'salary' => 7777],
['id' => 4, 'name' => '赵六', 'sex' => 'male', 'age' => 40, 'salary' => 11111],
['id' => 5, 'name' => '钱七', 'sex' => 'female', 'age' => 45, 'salary' => 9797],
['id' => 6, 'name' => '吴八', 'sex' => 'male', 'age' => 28, 'salary' => 7979],
['id' => 7, 'name' => '陈九', 'sex' => 'male', 'age' => 37, 'salary' => 8866],
];
/* demo: 模拟分页, 第三个参数默认为false */
$pageSize = 2;
$data = array_chunk($arr, $pageSize);
printfpre($data);
/* result: 返回结果是以分割成的数组为元素值的索引数组. 返回结果太长, 结果略.
*/
10. 自动生成
10.1 range(开始, 结束, 步长): 从”开始”值开始, 按照每隔”步长”个值, 获取一个值, 直到”结束”值, 返回获取的值组成的数组.
可以是数字, 字母
/* demo1: 从1开始, 每隔3个数, 取一个数值, 直到20 */
$arr = range(1, 20, 3);
echobr(implode(', ', $arr));
/* result: 1, 4, 7, 10, 13, 16, 19 */
/* demo2: 从'h'开始, 每隔4个字母, 取一个字母, 直到'z' */
$arr = range('h', 'z', 4);
echobr(implode(', ', $arr));
/* result: h, l, p, t, x */
10.2 array_fill(填充的元素的起始键名, 填充数量, 填充值): 用给定的值填充数组
/* demo1: 索引从5开始, 填充5个元素, 填充值为100 */
$arr = array_fill(5, 5, 100);
printfpre($arr);
/* result:
Array
(
[5] => 100
[6] => 100
[7] => 100
[8] => 100
[9] => 100
)
*/
10.2 array_fill_keys(键名数组, 值): 为指定的键名数组填充值
/* demo */
$res = array_fill_keys(['key1', 'key2', 'key3', 'key4'], 100);
printfpre($res);
/*
result:
Array
(
[key1] => 100
[key2] => 100
[key3] => 100
[key4] => 100
)
*/
array_pad(待处理数组, 填充后的数组元素总数, 填充值): 以指定长度将某个值填充进数组
$arr = [1, 2, 3, 4, 5];
/* demo1: 向右填充 */
$res = array_pad($arr, 10, 100);
echobr(implode(', ', $res));
/* result: 1, 2, 3, 4, 5, 100, 100, 100, 100, 100 */
/* demo1: 向左填充(田崇厚的数组元素总数为负数) */
$res = array_pad($arr, -10, 100);
printfpre($res);
/*
填充完成后的键名会重排
result:
Array
(
[0] => 100
[1] => 100
[2] => 100
[3] => 100
[4] => 100
[5] => 1
[6] => 2
[7] => 3
[8] => 4
[9] => 5
)
*/
11. 类型转换
11.1 list(变量1, 变量2…[可选]): 将数组中的值赋予一组变量(类似解构赋值)
/* demo1: */
$userInfo = ['zhangsan', '张三', '男', 34]; //['username' => 'zhangsan', 'realname' => '张三', 'sex' => '男', 'age' => 34];
list($username, $realname, $sex, $age) = $userInfo;
echobr("用户名: {$username}, 姓名: {$realname}, 性别: {$sex}, 年龄: {$age}");
/*
result:
用户名: zhangsan, 姓名: 张三, 性别: 男, 年龄: 34
*/
/* demo2: PHP7.1+ 支持关联数组 */
$arr = [
['id' => 1, 'name' => '张三', 'sex' => 'male', 'age' => 25, 'salary' => 9999],
['id' => 2, 'name' => '李四', 'sex' => 'female', 'age' => 30, 'salary' => 8888],
['id' => 3, 'name' => '王五', 'sex' => 'male', 'age' => 35, 'salary' => 7777],
['id' => 4, 'name' => '赵六', 'sex' => 'male', 'age' => 40, 'salary' => 11111],
['id' => 5, 'name' => '钱七', 'sex' => 'female', 'age' => 45, 'salary' => 9797],
['id' => 6, 'name' => '吴八', 'sex' => 'male', 'age' => 28, 'salary' => 7979],
['id' => 7, 'name' => '陈九', 'sex' => 'male', 'age' => 37, 'salary' => 8866],
];
foreach ($arr as ['id' => $id, 'name' => $name, 'salary' => $salary]) {
echobr("id: {$id}, name: {$name}, salary: {$salary}");
}
/*
result:
id: 1, name: 张三, salary: 9999
id: 2, name: 李四, salary: 8888
id: 3, name: 王五, salary: 7777
id: 4, name: 赵六, salary: 11111
id: 5, name: 钱七, salary: 9797
id: 6, name: 吴八, salary: 7979
id: 7, name: 陈九, salary: 8866
*/
/* demo3: PHP7.1+ 支持关联数组 */
$userInfo = ['username' => 'zhangsan', 'realname' => '张三', 'sex' => '男', 'age' => 34];
list('username' => $username, 'age' => $age) = $userInfo;
echobr("姓名: {$username}, 年龄: {$age}");
/* result: 姓名: zhangsan, 年龄: 34 */
/* demo4: 索引数组中只取出其中几个值 */
$userInfo = ['zhangsan', '张三', '男', 34];
list($username,,, $age) = $userInfo;
echobr("姓名: {$username}, 年龄: {$age}");
/* result: 姓名: zhangsan, 年龄: 34 */
// 另一种写法
list(0 => $username, 3 => $age) = $userInfo;
echobr("姓名: {$username}, 年龄: {$age}");
/* result: 姓名: zhangsan, 年龄: 34 */
11.2 implode(分隔符字符串, 待处理数组): 讲数组元素指定字符拼装成字符串
$arr = [1, 2, 3, 4, 5, 6];
$arrStr = implode(', ', $arr);
echobr($arrStr);
/* result: 1, 2, 3, 4, 5, 6 */
11.3 explode(分割用的字符串, 待处理字符串): 将字符串用指定的分割符分割成数组
$arrStr = '1, 2, 3, 4, 5, 6';
$arr = explode(', ', $arrStr);
dumpbr($arr);
/* result: array(6) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" [4]=> string(1) "5" [5]=> string(1) "6" } */
11.4 extract(待处理数组, 变量名异时处理常策略[可选], 变量名前缀[可选]): 将关联数组拆分成变量值对
- 变量名异常时处理策略有:
- EXTR_OVERWRITE: 如果有冲突,覆盖已有的变量。
- EXTR_SKIP: 如果有冲突,不覆盖已有的变量。
- EXTR_PREFIX_SAME: 如果有冲突,在变量名前加上前缀 prefix。
- EXTR_PREFIX_ALL: 给所有变量名加上前缀 prefix。
- EXTR_PREFIX_INVALID: 仅在非法/数字的变量名前加上前缀 prefix。
- EXTR_IF_EXISTS: 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。 举个例子,以下情况非常有用:定义一些有效变量,然后从 $_REQUEST 中仅导入这些已定义的变量。
- EXTR_PREFIX_IF_EXISTS: 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
- EXTR_REFS: 将变量作为引用提取。这有力地表明了导入的变量仍然引用了 array 参数的值。可以单独使用这个标志或者在 flags 中用 OR 与其它任何标志结合使用。
$userInfo = ['username1' => 'zhangsan', 'realname1' => '张三', 'sex1' => '男', 'age1' => 34];
extract($userInfo);
echobr("用户名: {$username1}, 姓名: {$realname1}, 性别: {$sex1}, 年龄: {$age1}");
/* result: 用户名: zhangsan, 姓名: 张三, 性别: 男, 年龄: 34 */
11.5 compact(变量名1, 变量名2…[可选]): 将一组变量名值对拼装成一个关联数组键值对
/* demo1: */
$username = 'lisi';
$realname = '李四';
$sex = '女';
$age = '23';
$arr = compact('username', 'realname', 'sex', 'age');
printfpre($arr);
/* result:
Array
(
[username] => lisi
[realname] => 李四
[sex] => 女
[age] => 23
)
*/
/* demo2: 也可以把全部或部分变量名以数组的形式传入 */
$keys = ['username', 'realname', 'sex', 'age'];
$arr1 = compact($keys);
printfpre($arr1);
/*
result:
Array
(
[username] => lisi
[realname] => 李四
[sex] => 女
[age] => 23
)
*/
12. 回调处理
12.1 array_filter(待处理数组, 处理数组元素值的回调): 遍历数组元素, 每个数组元素都用回调函数过滤
- 遍历数组元素, 每个数组元素都用回调函数处理,回调函数返回true(或转变为true的值), 则这个元素将被返回(键名保持不变); 反之, 这个元素将被过滤. 最后将所有返回的元素组成数组返回. 即, 返回的数组元素是原数组的子集.
// 创建一个1-20的数组
$arr = range(1, 20);
/* demo1: 过滤出所有的偶数元素 */
$res = array_filter($arr, function ($val) {
if ($val % 2 == 0) {
return true;
}
return false;
});
// 使用array_merge()函数重排键名
$res = array_merge($res);
printfpre($res);
12.2 array_map(处理数组元素值的回调, 待处理数组1, 待处理数组2…[可选]): 遍历待处理数组, 每个数组元素值都用回调处理,
- 把处理完成后的元素值组成新数组返回. 若有多个待处理数组, 则这些数组的元素个数要跟待处理数组一致, array_map()传入了多少个数组, 回调函数的参数就有多少个. 即, 返回的数组元素是待处理数组的元素值经回调处理后的值
/* demo1: 遍历数组, 1000以下不打折; 1000-3000打9折; 3001-5000打8折; 5001以上打7折 */
$prices = [888, 1024, 3099, 4799, 5555, 9999];
$cutPrices = array_map(function ($price) {
switch ($price) {
case ($price >= 1000 && $price <= 3000):
return $price * 0.9;
break;
case ($price > 3000 && $price <= 5000):
return $price * 0.8;
break;
case ($price > 5000):
return $price * 0.7;
break;
default:
return $price;
}
}, $prices);
printfpre($cutPrices);
/*
result:
Array
(
[0] => 888
[1] => 921.6
[2] => 2479.2
[3] => 3839.2
[4] => 3888.5
[5] => 6999.3
)
*/
/* demo2: 有多个数组的情况-计算面积 */
$length = [3, 5, 10];
$width = [7, 2, 4];
$area = array_map(function ($l, $w) {
return $l * $w;
}, $length, $width);
printfpre($area);
/*
result:
Array
(
[0] => 21
[1] => 10
[2] => 40
)
*/
12.3 array_walk(待处理数组, 处理数组元素的回调, 回调函数参数3[可选]): 遍历待处理数组, 对所有数组元素使用回调函数处理(直接处理原数组元素).
- 遍历待处理数组, 对所有数组元素使用回调函数处理(直接处理原数组元素).若处理完成, 返回true; 反之, 返回false.
- 回调函数的参数包括元素的键名和键值以及可能存在的回调函数参数3.
$arr = [1, 2, 3, 4, 5];
/* demo1: 所有数组元素乘以x */
array_walk($arr, function ($val, $key, $userdata) {
echobr("每个元素值将会乘以: {$userdata}");
$key += 1;
$res = $val * $userdata;
echobr("处理第{$key}个元素: {$val} 乘以 {$userdata} 等于 {$res}");
echobr();
}, 10);
/* result:
每个元素值将会乘以: 10
处理第1个元素: 1 乘以 10 等于 10
每个元素值将会乘以: 10
处理第2个元素: 2 乘以 10 等于 20
每个元素值将会乘以: 10
处理第3个元素: 3 乘以 10 等于 30
每个元素值将会乘以: 10
处理第4个元素: 4 乘以 10 等于 40
每个元素值将会乘以: 10
处理第5个元素: 5 乘以 10 等于 50
*/
学习心得
- 趁五一放假, 把数组相关函数作业补了, 老师总结的跟数组有关的函数都学习并举例了一遍. 心得就是, 多, 函数太多了, 照着php.net的相关文档理解并举例, 很容易, 但是记忆很难, 在合适的场景能想起某个合适的函数更难…