有时候你需要快速调换数组里的键名和键值。比如有一个城市代码映射表,想反过来通过城市名查代码。
array_flip()就是干这个的——把原数组的键名变成新数组的值,原数组的值变成新数组的键名。这个函数从PHP 4.0就有了。
语法格式
array array_flip(array $array): array
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| array | 要翻转的键值对数组 | 必填 |
返回值: 翻转后的数组。
重要限制: 原数组的值必须是整数或字符串,因为翻转后它会变成新数组的键名。PHP数组的键名只能是这两种类型。
示例1:基础用法
<?php
$user_roles = [
"admin" => 1,
"editor" => 2,
"viewer" => 3
];
$role_ids = array_flip($user_roles);
print_r($role_ids);
?>
输出:
Array
(
[1] => admin
[2] => editor
[3] => viewer
)
原来通过角色名查ID,翻转后可以通过ID查角色名。
示例2:索引数组翻转
<?php
$colors = ["红色", "绿色", "蓝色", "黄颜色"];
$flipped = array_flip($colors);
print_r($flipped);
?>
输出:
Array
(
[红色] => 0
[绿色] => 1
[蓝色] => 2
[黄颜色] => 3
)
索引数组翻转后,原来的数字索引(0、1、2、3)变成了值,原来的值变成了键名。
示例3:值重复的情况(后面的覆盖前面的)
<?php
$data = [
"a" => "shared",
"b" => "unique",
"c" => "shared",
"d" => "other"
];
$flipped = array_flip($data);
print_r($flipped);
?>
输出:
Array
(
[shared] => c
[unique] => b
[other] => d
)
注意:值"shared"出现了两次(对应键a和c)。翻转后,后面的键c覆盖了前面的键a。如果原数组的值有重复,翻转时会丢失数据。这是用array_flip()之前需要留意的坑。
示例4:不符合条件的值会报错
<?php
// 下面这段代码会报错
$invalid = [
"name" => "张伟",
"score" => 85,
"data" => ["nested", "array"] // 数组不能作为键名
];
// $flipped = array_flip($invalid); // 取消注释会报错
// 浮点数也不行
$with_float = ["a" => 1.5, "b" => 2.5];
// $flipped2 = array_flip($with_float); // 报错
echo "只有整数和字符串才能作为键名\n";
?>
个人经验分享
-
常见使用场景
-
快速去重:
array_flip()两次调用可以去掉重复值$unique = array_flip(array_flip($array)); // 去重并保留之后出现的顺序 -
反向查找:构建键值倒排索引
-
数据映射转换:比如状态码和状态名称互转
-
验证值是否存在:翻转后用
isset()比in_array()快得多
-
-
性能方面
array_flip()内部是C实现的,比手写循环快很多。用翻转后的数组做键名查找(isset($flipped[$value]))比in_array()快得多,因为键名查找是O(1)复杂度,而in_array()是O(n)。 -
去重时的注意点
$arr = ["a", "b", "a", "c", "b"]; $flipped = array_flip($arr); // ["a"=>2, "b"=>4, "c"=>3] $unique = array_flip($flipped); // [2=>"a", 4=>"b", 3=>"c"] // 得到的索引不是连续的如果需要重新索引,加个
array_values()。 -
配合array_key_exists()使用
翻转后,用array_key_exists()检查某个值是否存在,效率远高于in_array()。
示例5:代码号学习编程场景
<?php
// 场景:学生ID和姓名的双向查找
$students = [
"code001" => "张伟",
"code002" => "李芳",
"code003" => "王磊",
"code004" => "赵敏",
"code005" => "刘强"
];
// 创建反向索引(姓名 => ID)
$name_to_id = array_flip($students);
// 根据ID查姓名
function get_name_by_id($id, $students) {
return $students[$id] ?? "未知ID";
}
// 根据姓名查ID
function get_id_by_name($name, $name_to_id) {
return $name_to_id[$name] ?? "未知姓名";
}
echo "code003对应的姓名:" . get_name_by_id("code003", $students) . "\n";
echo "赵敏对应的ID:" . get_id_by_name("赵敏", $name_to_id) . "\n";
?>
输出:
code003对应的姓名:王磊
赵敏对应的ID:code004
示例6:快速数组去重
<?php
$raw_data = ["apple", "banana", "apple", "orange", "banana", "grape", "apple"];
// 方法1:array_unique(保留键名)
$unique1 = array_unique($raw_data);
// 方法2:array_flip两次(效率更高)
$unique2 = array_flip(array_flip($raw_data));
// 方法3:如果需要重新索引
$unique3 = array_values(array_unique($raw_data));
echo "原始数组:" . count($raw_data) . "个元素\n";
echo "去重后:" . count($unique2) . "个元素\n";
print_r($unique2);
?>
输出:
原始数组:7个元素
去重后:4个元素
Array
(
[apple] => 2
[banana] => 4
[orange] => 3
[grape] => 5
)
注意array_flip两次去重会保留之后一次出现的位置作为键名,这和array_unique的默认行为略有不同。
示例7:处理翻转时可能出现的类型错误
<?php
$data = [
"user1" => 1001,
"user2" => 1002,
"user3" => "valid_string",
"user4" => null, // null不能作为键名
"user5" => 3.14, // 浮点数不能作为键名
];
// 安全翻转:过滤掉不能作为键名的值
function safe_array_flip($array) {
$result = [];
foreach ($array as $key => $value) {
if (is_int($value) || is_string($value)) {
$result[$value] = $key;
}
// 不合法的值跳过
}
return $result;
}
$safe_flipped = safe_array_flip($data);
print_r($safe_flipped);
?>
输出:
Array
(
[1001] => user1
[1002] => user2
[valid_string] => user3
)
本节课程知识要点
-
array_flip()交换数组的键名和键值 -
原数组的值必须能被当作新数组的键名(整数或字符串)
-
原数组的值重复时,后面的值会覆盖前面的(数据可能丢失)
-
浮点数、布尔值、数组、对象不能作为值参与翻转
-
常用于反向查找、快速去重、构建索引
-
翻转后用
isset()查找比in_array()快得多 -
从PHP 4.0开始可用