PHP array_column 少了一筆?先查重複鍵名與缺少的商品代碼

把匯入的商品清單轉成「商品代碼 → 商品名稱」時,array_column() 的第三個參數很好用。但如果兩列都用同一個代碼,結果只會剩下一個名稱。先決定一個代碼應該代表一筆商品,還是一組商品,再選擇輸出格式。

同一代碼出現兩次,後一筆會覆蓋前一筆

$rows = [
    ['sku' => 'A', 'name' => '帆布袋'],
    ['sku' => 'A', 'name' => '禮盒'],
    ['name' => '試用品'],
];

$names = array_column($rows, 'name', 'sku');
print_r($names);
// A => 禮盒
// 0 => 試用品

第二個參數 name 指定要取的值,第三個參數 sku 指定用哪個欄位的值當鍵名。兩筆 A 最後寫入同一個鍵,後面的「禮盒」取代了「帆布袋」。第三筆沒有 sku,PHP 仍把名稱加進結果,並給它自動數字鍵。本例是 0,但若前面已用整數鍵 8,下一個自動鍵可能是 9,所以別用「鍵等於 0」判斷資料是否缺代碼。

若只要按順序取出名稱,可以省略第三個參數,直接用 array_column($rows, 'name')。三個名稱會依原順序保留,結果以數字索引排列。

每個代碼只能有一筆時,匯入前先擋住重複資料

以下沿用上面的 $rows。匯入規則要求商品代碼和名稱為字串,遇到空代碼、缺欄位或重複代碼就停止,讓操作人員回去修原始資料。

$bySku = [];
foreach ($rows as $row) {
    $sku = $row['sku'] ?? null;
    $name = $row['name'] ?? null;
    if (!is_string($sku) || trim($sku) === '' || !is_string($name)) {
        throw new InvalidArgumentException('商品代碼或名稱不合格式');
    }

    $sku = trim($sku);
    if (array_key_exists($sku, $bySku)) {
        throw new InvalidArgumentException('重複商品代碼:' . $sku);
    }
    $bySku[$sku] = $name;
}

這段會在第二筆 A 停下,前一筆不會被改掉。修好重複代碼後再次匯入,第三筆缺代碼也會被攔下。若代碼可能是純數字字串,還要留意 PHP 陣列的鍵名規則,例如字串 '8' 會轉成整數鍵 8。如果下游要求鍵名保留為字串,可以在內部索引加固定前綴,或保留資料列,將代碼當作欄位傳遞。

一個代碼允許多筆時,改成一組名稱

例如同一個活動代碼可以列出多種贈品,確認每列都有有效的 sku 和 name 後,用陣列保存整組名稱。以下只取原例的前兩筆有效資料。

$namesBySku = [];
foreach (array_slice($rows, 0, 2) as $row) {
    $namesBySku[$row['sku']][] = $row['name'];
}
print_r($namesBySku['A']);
// [0 => 帆布袋, 1 => 禮盒]

接到新資料來源時,可以用三種小樣本先跑一次:代碼全不同、代碼重複、某列缺代碼。確認結果是保留、分組還是拒收,再接到正式匯入流程。

封面為 AI 生成的分組概念插畫。

參考資料

原文鏈接:https://wntheme.com/php-array-column-index-key-duplicates/,轉載請註明出處。
0
顯示驗證碼
沒有帳號?註冊  忘記密碼?