PHP array_map() 映射處理
array_map() 函數用來將回呼函數應用到陣列的每個元素上,回傳處理後的新陣列。
基本用法
<?php
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(fn($n) => $n * 2, $numbers);
print_r($doubled); // [2, 4, 6, 8, 10]
?>
語法
array_map(?callable $callback, array $array, array ...$arrays): array
$callback:回呼函數$array:要處理的陣列$arrays:額外的陣列(可選)- 回傳值:處理後的新陣列
使用具名函數
<?php
function square($n) {
return $n * $n;
}
$numbers = [1, 2, 3, 4, 5];
$squares = array_map('square', $numbers);
print_r($squares); // [1, 4, 9, 16, 25]
// 使用內建函數
$strings = ['hello', 'world', 'php'];
$upper = array_map('strtoupper', $strings);
print_r($upper); // ['HELLO', 'WORLD', 'PHP']
?>
使用匿名函數
<?php
$numbers = [1, 2, 3, 4, 5];
// 匿名函數
$result = array_map(function($n) {
return $n * 2 + 1;
}, $numbers);
print_r($result); // [3, 5, 7, 9, 11]
?>
使用箭頭函數(PHP 7.4+)
<?php
$numbers = [1, 2, 3, 4, 5];
$result = array_map(fn($n) => $n ** 2, $numbers);
print_r($result); // [1, 4, 9, 16, 25]
?>
處理多個陣列
當傳入多個陣列時,回呼函數會接收每個陣列對應位置的元素:
<?php
$arr1 = [1, 2, 3];
$arr2 = [10, 20, 30];
$result = array_map(fn($a, $b) => $a + $b, $arr1, $arr2);
print_r($result); // [11, 22, 33]
?>
陣列長度不同時
較短的陣列會用 null 填充:
<?php
$arr1 = [1, 2, 3, 4, 5];
$arr2 = [10, 20, 30];
$result = array_map(fn($a, $b) => $a + ($b ?? 0), $arr1, $arr2);
print_r($result); // [11, 22, 33, 4, 5]
?>
null 回呼:建立多維陣列
當回呼是 null 時,會將多個陣列組合成多維陣列:
<?php
$names = ['Alice', 'Bob', 'Charlie'];
$ages = [25, 30, 35];
$result = array_map(null, $names, $ages);
print_r($result);
// [
// ['Alice', 25],
// ['Bob', 30],
// ['Charlie', 35]
// ]
?>
保留鍵
array_map() 會保留陣列的鍵:
<?php
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
$result = array_map(fn($n) => $n * 2, $arr);
print_r($result);
// ['a' => 2, 'b' => 4, 'c' => 6]
?>
常見應用
資料轉換
<?php
$users = [
['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com'],
];
// 提取名稱
$names = array_map(fn($user) => $user['name'], $users);
print_r($names); // ['Alice', 'Bob']
// 或使用 array_column
$names = array_column($users, 'name');
?>
格式化資料
<?php
$prices = [10.5, 20.75, 30.125];
$formatted = array_map(fn($p) => sprintf('$%.2f', $p), $prices);
print_r($formatted); // ['$10.50', '$20.75', '$30.13']
?>
清理輸入
<?php
$inputs = [' Alice ', ' Bob ', ' Charlie '];
$cleaned = array_map('trim', $inputs);
print_r($cleaned); // ['Alice', 'Bob', 'Charlie']
// 多重處理
$inputs = [' HELLO ', ' WORLD '];
$cleaned = array_map(fn($s) => ucfirst(strtolower(trim($s))), $inputs);
print_r($cleaned); // ['Hello', 'World']
?>
建立選項陣列
<?php
$ids = [1, 2, 3, 4, 5];
$options = array_map(
fn($id) => ['value' => $id, 'label' => "Option $id"],
$ids
);
print_r($options);
// [
// ['value' => 1, 'label' => 'Option 1'],
// ['value' => 2, 'label' => 'Option 2'],
// ...
// ]
?>
計算多個值
<?php
$numbers = [1, 2, 3, 4, 5];
$stats = array_map(
fn($n) => [
'original' => $n,
'squared' => $n ** 2,
'cubed' => $n ** 3
],
$numbers
);
print_r($stats);
?>
使用外部變數
<?php
$factor = 10;
$numbers = [1, 2, 3, 4, 5];
// 匿名函數需要 use
$result = array_map(function($n) use ($factor) {
return $n * $factor;
}, $numbers);
// 箭頭函數自動捕獲
$result = array_map(fn($n) => $n * $factor, $numbers);
print_r($result); // [10, 20, 30, 40, 50]
?>
array_map vs foreach
<?php
$numbers = [1, 2, 3, 4, 5];
// 使用 array_map
$doubled = array_map(fn($n) => $n * 2, $numbers);
// 使用 foreach
$doubled = [];
foreach ($numbers as $n) {
$doubled[] = $n * 2;
}
// 兩者結果相同,選擇適合的方式
?>
效能考量
<?php
// 對於簡單操作,foreach 可能更快
$numbers = range(1, 100000);
// array_map
$start = microtime(true);
$result = array_map(fn($n) => $n * 2, $numbers);
$time1 = microtime(true) - $start;
// foreach
$start = microtime(true);
$result = [];
foreach ($numbers as $n) {
$result[] = $n * 2;
}
$time2 = microtime(true) - $start;
// 差異通常不大,選擇可讀性更好的方式
?>
注意事項
<?php
// array_map 總是回傳陣列(不同於 array_filter)
$numbers = [1, 2, 3];
$result = array_map(fn($n) => null, $numbers);
print_r($result); // [null, null, null]
// 回呼函數應該回傳值
$numbers = [1, 2, 3];
$result = array_map(function($n) {
echo $n; // 只有副作用,沒有 return
}, $numbers);
print_r($result); // [null, null, null]
?>