How to do sum of array item's value until not reached at specified value?

丶灬走出姿态 提交于 2020-01-16 11:27:06

问题


I want to do sum of array item's value until not reached at specified value.

Let me explain in details.

I want 20 k.g value in each box , So following is my array.

Array
(
    [0] => Array
        (
            [product_id] => 2
            [customer_id] => 1820
            [order_id] => M-AAH-959
            [quantity] => 5
            [weight] => 1.3
            [cubic] => 0.00267
            [total_weight] => 6.5
            [total_cubic] => 0.00267
        )

    [1] => Array
        (
            [product_id] => 3
            [customer_id] => 1820
            [order_id] => M-AAH-959
            [quantity] => 6
            [weight] => 1.5
            [cubic] => 0.00348
            [total_weight] => 9
            [total_cubic] => 0.00348
        )

    [2] => Array
        (
            [product_id] => 8
            [customer_id] => 1820
            [order_id] => M-AAH-959
            [quantity] => 7
            [weight] => 1.5
            [cubic] => 0.00267
            [total_weight] => 10.5
            [total_cubic] => 0.00267
        )

)

You can see in above array there are 3 fields quantity,weight & total_weight.

So during loop i want to set 20 value to single box from sum of each items weight. we can take quantity & weight from any three items for set 20 value for each.

So output will be..

Array (

     [0] => Array('box_item'=>20)
     [1] => Array('box_item'=>6)

)

Let me explain output array..

You can see total_weigh of First array 6.5 & second 9 & third 10.5

I want to set 20 value per box, So calculation will be

6.5 + 9 = 15.5 , then add 4.5 from third array like 1.5*3 = 4.5

So first box is for 20 & remain weight value is 6 so it'll be set is for second box.

Note: Currently i have taken only 3 items for example purpose but there will be more items here and I have to set 20 k.g value for each for from weight of items value.

I have used following code but not helpful. This code is not given proper output

// First calculate the total
foreach ($main as $key => $package) {
    $packageInfo[$key]['total_weight'] = $package['quantity'] * $package['weight'];

}

// Then check count the packages ?
    $packages = [];
    $packageTotalWeight = 0;
    $packageItemWeight = 0;
    $cubicTotal = 0;

    foreach ($packageInfo as $key => $package) {
        if(($packageTotalWeight + $package['total_weight']) > 20){
            $packages[]['final_total'] = $packageTotalWeight;
            $packageTotalWeight = $package['total_weight'];       
        } else {            
            $packageTotalWeight += $package['total_weight'];            
        }

    }

回答1:


This function will "pack" the boxes for you, selecting from each product in turn until a box reaches the maximum box weight, then starting a new one:

function pack_boxes($products, $box_weight) {
    $boxes = array();
    $this_box_weight = 0;
    $box_number = 0;
    foreach ($products as $product) {
        // will all this product fit?
        if ($product['total_weight'] < $box_weight - $this_box_weight) {
            // yes - add this product to the box
            $boxes[$box_number][] = $product;
            $this_box_weight += $product['total_weight'];
            $boxes[$box_number]['box_weight'] = $this_box_weight;
        }
        else {
            // no - add the part that will fit to this box
            $num_products = floor(($box_weight - $this_box_weight) / $product['weight']);
            $balance = $product['quantity'] - $num_products;
            $product['quantity'] = $num_products;
            $product['total_weight'] = $num_products * $product['weight'];
            $boxes[$box_number][] = $product;
            $boxes[$box_number]['box_weight'] = $this_box_weight + $num_products * $product['weight'];
            // add the balance to a new box
            $box_number++;
            $product['quantity'] = $balance;
            $this_box_weight = $product['total_weight'] = $balance * $product['weight'];
            $boxes[$box_number][] = $product;
            $boxes[$box_number]['box_weight'] = $this_box_weight;
        }
    }
    return $boxes;
}

The total weight in each box is available in $boxes[*]['box_weight'].

Sample usage (12 is maximum weight per box) to get the box weights per box:

$boxes = pack_boxes($products, 12);
print_r(array_column($boxes, 'box_weight'));

Output (box weights only):

Array
(
    [0] => 11
    [1] => 12
    [2] => 3
)

Or the full data result:

print_r($boxes);

Output

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [product_id] => 2
                    [customer_id] => 1820
                    [order_id] => M-AAH-959
                    [quantity] => 5
                    [weight] => 1.3
                    [cubic] => 0.00267
                    [total_weight] => 6.5
                    [total_cubic] => 0.00267
                )    
            [box_weight] => 11
            [1] => Array
                (
                    [product_id] => 3
                    [customer_id] => 1820
                    [order_id] => M-AAH-959
                    [quantity] => 3
                    [weight] => 1.5
                    [cubic] => 0.00348
                    [total_weight] => 4.5
                    [total_cubic] => 0.00348
                )    
        )    
    [1] => Array
        (
            [0] => Array
                (
                    [product_id] => 3
                    [customer_id] => 1820
                    [order_id] => M-AAH-959
                    [quantity] => 3
                    [weight] => 1.5
                    [cubic] => 0.00348
                    [total_weight] => 4.5
                    [total_cubic] => 0.00348
                )    
            [box_weight] => 12
            [1] => Array
                (
                    [product_id] => 8
                    [customer_id] => 1820
                    [order_id] => M-AAH-959
                    [quantity] => 5
                    [weight] => 1.5
                    [cubic] => 0.00267
                    [total_weight] => 7.5
                    [total_cubic] => 0.00267
                )    
        )    
    [2] => Array
        (
            [0] => Array
                (
                    [product_id] => 8
                    [customer_id] => 1820
                    [order_id] => M-AAH-959
                    [quantity] => 2
                    [weight] => 1.5
                    [cubic] => 0.00267
                    [total_weight] => 3
                    [total_cubic] => 0.00267
                )    
            [box_weight] => 3
        )    
)

Demo on 3v4l.org




回答2:


You can get full sum and then pass each 20 to one element in resultant array:

$total_sum = array_sum(array_column($packageInfo,'total_weight'));

$boxes = ceil($total_sum/20);        // count of boxes

for($i=0;$i<$boxes;$i++){
    $res[$i]['box_item'] = ($total_sum - $i*20)>20 ? 20 : ($total_sum - $i*20);
}

Demo

Output:

Array
(
    [0] => Array
        (
            [box_item] => 20
        )

    [1] => Array
        (
            [box_item] => 6
        )

)


来源:https://stackoverflow.com/questions/59421440/how-to-do-sum-of-array-items-value-until-not-reached-at-specified-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!