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]
?>