Add to an array value (+1)

Viewed 64502

I have an array

$hourly = array(
        "01" => "0",
        "02" => "0",
        "03" => "0",
        "04" => "0",
        "05" => "0",
        "06" => "0",
        "07" => "0",
        "08" => "0",
        "09" => "0",
        "10" => "0",
        "11" => "0",
        "12" => "0",
        "13" => "0",
        "14" => "0",
        "15" => "0",
        "16" => "0",
        "17" => "0",
        "18" => "0",
        "19" => "0",
        "20" => "0",
        "21" => "0",
        "22" => "0",
        "23" => "0"
            );

And I have a bunch of data like "01" and "03" and "21" and I want to add (+1) to that specific value in the array. So with the data set "01","03","21","01","22" the resulting array would be

$hourly = array(
        "01" => "2",
        "02" => "0",
        "03" => "1",
        "04" => "0",
        "05" => "0",
        "06" => "0",
        "07" => "0",
        "08" => "0",
        "09" => "0",
        "10" => "0",
        "11" => "0",
        "12" => "0",
        "13" => "0",
        "14" => "0",
        "15" => "0",
        "16" => "0",
        "17" => "0",
        "18" => "0",
        "19" => "0",
        "20" => "0",
        "21" => "1",
        "22" => "1",
        "23" => "0"
            );

How could I go about doing that? Is there a function to add 1 to an array element?

6 Answers

Dealing with leading zeros is messy, no matter which way you approach it. You are either going to have to deal with mixed string/integer indexes, OR you are going to have to make sure you force everything into integer, but then remember to put the leading zero back if displaying it is important.

If you ever manipulate an array with something like array_merge(), you had better force all indexes to integer, because it will renumber integer indexes if there are gaps in the sequence.

If you want to preserve the leading zeros in the indexes

The following will only work if the inputs are really in an array and the values are consistent (ie "one" always occurs as "01" and never as "1" (or vice-versa)):

$counts = array_count_values( $inputs );

Because of the leading zeros for values <10 they are interpreted as strings, which you may or may not notice depending on how you access the counts. If you use a hardcoded index, you need to be sure to include the leading zero, eg $counts["01"] not $counts["1"]. If you only care about the values that have been seen, a simple foreach...as will suffice:

foreach( $counts as $value => $count ){ print "$value => $count\n"; }

If you are going to iterate through every possible value (or otherwise access them randomly), you need a bit of a kludge:

function lpad( $index ){ return str_pad($index,2,"0",STR_PAD_LEFT); }
for($i=0;$i<24;$i++){ print ($counts[lpad($i)]??0)." "; }

or if you want to avoid a function call for performance

$lpad = array_keys($hourly); ### IMPORTANT! ASSUMES $hourly ACTUALLY STARTS WITH "00"
for($i=0;$i<24;$i++){ print ($counts[$lpad[$i]]??0)." "; }

If you have a version of PHP that doesn't have ?? the body of the for loop should be something like

print (is_null( $p = $counts[$lpad[$i]] )? 0 : $p )." ";

If you want to force indexes with leading zeros into integers

Sparse counts (some hours skipped if they never appear)

$counts = array_reduce( $inputs, function($c, $i){ $c[(integer)$i]++; return $c; }, array() );

Full range of counts (all hours, even if count is zero)

$counts = array_reduce( $inputs, function($c, $i){ $c[(integer)$i]++; return $c; }, array_fill( 0, 24, 0 ));
Related