skip to Main Content

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;
        }
    }
}

2

Answers


  1. 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
            )
    )
    
    Login or Signup to reply.
  2. 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);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search