PHP多维数组按二级元素值获取对应键名的最优高效方法
搜索PHP多维数组二级值获取对应一级键名的最优方案
针对你给出的这个多维数组场景,最快最优的方法得分两种情况来聊——毕竟高频查询和单次查询的优化方向完全不一样:
一、高频查询:提前构建反向映射表(性能天花板)
如果你的业务需要反复搜索不同的二级值,那提前做一个「值→对应一级键名数组」的反向索引绝对是最优解。因为构建一次之后,后续每次查询都是O(1)的直接取值,完全不用再遍历原数组,高频场景下性能碾压所有单次遍历的方法。
看代码示例:
$test = array( 'name_01' => array('yellow', 'red', 'blue', 'black', 'white', 'purple'), 'name_02' => array('red', 'blue', 'white', 'green'), 'name_03' => array('blue', 'pink', 'purple', 'blue'), 'name_04' => array('white', 'black', 'red'), 'name_05' => array('yellow', 'white', 'pink', 'black') ); // 构建反向映射表,给每个颜色绑定对应的一级键 $reverseMap = []; foreach ($test as $key => $colors) { // 先去重,避免同一个键被重复加到同一个颜色的列表里 $uniqueColors = array_unique($colors); foreach ($uniqueColors as $color) { if (!isset($reverseMap[$color])) { $reverseMap[$color] = []; } $reverseMap[$color][] = $key; } } // 搜索"pink",用??处理值不存在的情况 $result = $reverseMap['pink'] ?? []; print_r($result); // 输出 Array ( [0] => name_03 [1] => name_05 )
这里用array_unique处理二级数组是关键——不然像name_03里的两个blue会把name_03重复加到blue的列表里,既浪费空间又没必要。
二、单次/低频查询:直接高效遍历
如果只是偶尔搜一次,那就没必要额外建映射表占内存了,直接遍历原数组就行。这里要注意用高效的存在性判断方式:
基础版:用in_array
$test = array( 'name_01' => array('yellow', 'red', 'blue', 'black', 'white', 'purple'), 'name_02' => array('red', 'blue', 'white', 'green'), 'name_03' => array('blue', 'pink', 'purple', 'blue'), 'name_04' => array('white', 'black', 'red'), 'name_05' => array('yellow', 'white', 'pink', 'black') ); $searchValue = 'pink'; $result = []; foreach ($test as $key => $colors) { // 字符串场景下用in_array足够,混合类型可以加第三个参数true做严格匹配 if (in_array($searchValue, $colors)) { $result[] = $key; } } print_r($result); // 输出 Array ( [0] => name_03 [1] => name_05 )
优化版:二级数组转关联数组(长数组更高效)
如果你的二级数组元素特别多,in_array的遍历判断会有点慢,这时候可以把二级数组转成键为元素值的关联数组,用isset来判断(O(1)时间):
foreach ($test as $key => $colors) { $colorMap = array_flip($colors); if (isset($colorMap[$searchValue])) { $result[] = $key; } }
array_flip是O(k)的操作,但后续的isset是瞬间完成,对于长二级数组来说,比反复用in_array遍历要快不少。
内容的提问来源于stack exchange,提问作者Phantom
相关产品推荐
相关产品推荐

