簡體   English   中英

PHP 將具有相似鍵的數組合並,並對一些鍵求和

[英]PHP merge array with similar keys, and sum some keys

在打擾這個令人敬畏的社區之前,我真的為此苦苦掙扎了一天多,但我沒有任何運氣。

我有一個看起來像這樣的數組

$Data = [
  [
   'code' => 'P-01',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 3
  ],
 [
   'code' => 'P-09',
   'firstname' => 'Roy',
   'lastname' => 'Gauthier',
   'quantity' => 14
  ],
 [
   'code' => 'P-24',
   'firstname' => 'Marin',
   'lastname' => 'Fortin',
   'quantity' => 24
  ],
 [
   'code' => 'P-03',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 7
  ],
 [
   'code' => 'P-01',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 9
  ],
];

所以我想合並數組所以我有這樣的數組

$Data = [
  [
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'combined' => [
     'code' => 'P-01',
     'quantity' => 12 
   ],
   [
     'code'=> 'P-03',
     'quantity' => 7
   ]
  ],
  [
   'firstname' => 'Roy',
   'lastname' => 'Gauthier',
   'combined' => [
     'code' => 'P-09',
     'quantity' => 14 
   ]
  ],
  [
   'firstname' => 'Marin',
   'lastname' => 'Fortin',
   'combined' => [
     'code' => 'P-24',
     'quantity' => 24
   ]
  ],
];

如您所見,如果“代碼”相同,我需要對數量求和。 提前致謝

在以下示例中,您將獲得具有唯一代碼鍵的新合並數組。 此外,它將前一個數量添加到下一個數量。

$Merged = [];
foreach ($Data as $value) {
  if (isset($Merged[$value['code']])) {
    $Merged[$value['code']]['quantity'] += $value['quantity'];
  } else {
    $Merged[$value['code']] = $value;
  }
}

Output

Array
(
    [P-01] => Array
        (
            [code] => P-01
            [firstname] => Sam
            [lastname] => Bouchard
            [quantity] => 12
        )

    [P-09] => Array
        (
            [code] => P-09
            [firstname] => Roy
            [lastname] => Gauthier
            [quantity] => 14
        )

    [P-24] => Array
        (
            [code] => P-24
            [firstname] => Marin
            [lastname] => Fortin
            [quantity] => 24
        )

    [P-03] => Array
        (
            [code] => P-03
            [firstname] => Sam
            [lastname] => Bouchard
            [quantity] => 7
        )

)

輸入數據

請注意,您顯示的數組在格式上有一些錯誤(可能是拼寫錯誤)。 我們將使用:

$data = [
  [
   'code' => 'P-01',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 3
  ],
 [
   'code' => 'P-09',
   'firstname' => 'Roy',
   'lastname' => 'Gauthier',
   'quantity' => 14
  ],
 [
   'code' => 'P-24',
   'firstname' => 'Marin',
   'lastname' => 'Fortin',
   'quantity' => 24
  ],
 [
   'code' => 'P-03',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 7
  ],
 [
   'code' => 'P-01',
   'firstname' => 'Sam',
   'lastname' => 'Bouchard',
   'quantity' => 9
  ]
];

變換數組

首先,我們想將數組轉換為我們可以輕松使用的數據結構,同時我們可以組合和更新數量。

在這種情況下,我們將在firstname -> lastname -> code三個級別上重新組織索引

// Define the array for output of transformation
$firstnameIndexArray = [];

// Loop through all current data points
foreach($data as $point){

    // Set a pointer by reference to decrease the length of the next line(!) hopefully 
    // making it more readable
    $pointer   = &$firstnameIndexArray[$point['firstname']][$point['lastname']][$point['code']];

    // Update the quantity
    // $pointer ?? 0... sets to 0 if $pointer doesn't contain a value/exist
    $pointer   = ($pointer ?? 0) + $point["quantity"];
}

現在我們已經完成了一個數組,如下所示:

Array
(
    [Sam] => Array
        (
            [Bouchard] => Array
                (
                    [P-01] => 12
                    [P-03] => 7
                )

        )

    [Roy] => Array
        (
            [Gauthier] => Array
                (
                    [P-09] => 14
                )

        )

    [Marin] => Array
        (
            [Fortin] => Array
                (
                    [P-24] => 24
                )

        )

)

以正確的格式重新制作數組

現在剩下要做的就是以我們選擇的格式循環遍歷轉換后的數組和 output...

// Define the output array
$finalArray = [];

// Loop through first level of array
foreach($firstnameIndexArray as $firstname => $lastnameIndexarray){

    // Loop through second level of array
    foreach($lastnameIndexarray as $lastname => $codeIndexArray){

        // Define the combined array of code/value pairs
        $combinedArray = [];

        // Loop though each code/value pair
        foreach($codeIndexArray as $code => $quantity){

            // Make the combined array in the correct format
            $combinedArray[] = [
                'code'     => $code,
                'quantity' => $quantity
            ];
        }

        // Add the person to the final array
        $finalArray[] = [
            'firstname' => $firstname,
            'lastname' => $lastname,
            'combined' => $combinedArray
        ];
    }
}

這給了 output 之類的:

Array
(
    [0] => Array
        (
            [firstname] => Sam
            [lastname] => Bouchard
            [combined] => Array
                (
                    [0] => Array
                        (
                            [code] => P-01
                            [quantity] => 12
                        )

                    [1] => Array
                        (
                            [code] => P-03
                            [quantity] => 7
                        )

                )

        )

    [1] => Array
        (
            [firstname] => Roy
            [lastname] => Gauthier
            [combined] => Array
                (
                    [0] => Array
                        (
                            [code] => P-09
                            [quantity] => 14
                        )

                )

        )

    [2] => Array
        (
            [firstname] => Marin
            [lastname] => Fortin
            [combined] => Array
                (
                    [0] => Array
                        (
                            [code] => P-24
                            [quantity] => 24
                        )

                )

        )

)

沒有注釋的代碼

$firstnameIndexArray = [];
foreach($data as $point){
    $pointer   = &$firstnameIndexArray[$point['firstname']][$point['lastname']][$point['code']];
    $pointer   = ($pointer ?? 0) + $point["quantity"];
}

$finalArray = [];
foreach($firstnameIndexArray as $firstname => $lastnameIndexarray){
    foreach($lastnameIndexarray as $lastname => $codeIndexArray){
        $combinedArray = [];
        foreach($codeIndexArray as $code => $quantity){
            $combinedArray[] = [
                'code'     => $code,
                'quantity' => $quantity
            ];
        }
        $finalArray[] = [
            'firstname' => $firstname,
            'lastname' => $lastname,
            'combined' => $combinedArray
        ];
    }
}

可能的方法是使用“代碼”作為新數組的索引:

創建一個新的結果數組

$combined = [];

遍歷 $Data 並將每個項目放入 $item 對於每個 $item 獲取代碼作為 $key 檢查您是否已經在組合數組中具有該 $key 的值

if (isset($combined[$key]))) {...}

如果沒有,則使用該 $key 將項目添加到數組

$newItem = $this->createNewStructureFromItem($item);
$combined[$key] = $newItem;

如果您已經在組合數組中擁有該鍵,則僅更新數量

$existingItem = $combined[$key];
$updatedItem = $this->increaseQuantity($existingItem, $item);
$combined[$key] = $updatedItem;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM