Home > Software design >  Divide integer by qualifying rows and add to column values
Divide integer by qualifying rows and add to column values

Time:10-16

I need the variable $tsp to be evenly added to the value in the "count" field, but only in those fields where the "count" is greater than 0 .

$tsp = 9;
$fin = [
    "1701" => ["total_space" => 0, "count" => 0],
    "1702" => ["total_space" => 0, "count" => 0], 
    "1703" => ["total_space" => 20, "count" => 20], 
    "1704" => ["total_space" => 28, "count" => 28]
];

that 's what the result should be

$tsp = 9;
$fin = [
    "1701" => ["total_space" => 0, "count" => 0],
    "1702" => ["total_space" => 0, "count" => 0], 
    "1703" => ["total_space" => 20, "count" => 25], //  5
    "1704" => ["total_space" => 28, "count" => 32] //  4
];

I wrote a loop, but it increases both fields by 9,

for ($i = $tsp; $i > 0; $i--) {
    foreach ($fin as $dt => $s) {
        if ($s['count'] > 0) {
            $fin[$dt]['count'] = $s['count']   1;
            $tsp = $tsp - 1;
        }
    }
}

CodePudding user response:

The issue with your attempted implementation is that you iterate over all entries in the $fin array and increment the counter for each $tsp. You only want to increment one of those, not all ...

This would be a possible solution:

<?php
$tsp=9;
$fin = [
    "1701"=> ["total_space"=> 0, "count"=> 0],
    "1702"=> ["total_space"=> 0, "count"=> 0], 
    "1703"=> ["total_space"=> 20, "count"=> 20], 
    "1704"=> ["total_space"=> 28, "count"=> 28]
];

while ($tsp > 0) {
    array_walk($fin, function(&$s) use (&$tsp) {
        if ($tsp > 0 && $s['count'] > 0) {
            $s['count']  ;
            $tsp--;
        }
    });
}

print_r($fin);

The output obviously is:

Array
(
    [1701] => Array
        (
            [total_space] => 0
            [count] => 0
        )
    [1702] => Array
        (
            [total_space] => 0
            [count] => 0
        )
    [1703] => Array
        (
            [total_space] => 20
            [count] => 25
        )
    [1704] => Array
        (
            [total_space] => 28
            [count] => 32
        )
)

CodePudding user response:

Rather than brute forcing the arithmetic with single increments and decrements in a loop which re-checks for 0 counts, use a technique with lower time complexity that doesn't ever revisit 0 count rows.

My snippet filters the array once, then only adds value to qualifying rows once.

Code: (Demo)

$qualifiers = array_filter($fin, fn($row) => $row['count']);
$divideBy = count($qualifiers);

foreach ($qualifiers as $id => $row) {
    $tsp -= $toAdd = ceil($tsp / $divideBy);
    --$divideBy;
    $fin[$id]['count']  = $toAdd;
}
var_export($fin);
  • Related