Add to an array value (+1)
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 a开发者_高级运维dd 1 to an array element?
$updates = array("01","03","21","01","22");
foreach($updates as $num) {
$hourly[$num]++;
}
$hours = array("01", "03", "21" );
foreach($hours as $hour) {
$hourly[$hour] += 1;
}
Normally, you'd be able to do:
$array["key"]++;
However, your arrays have a few peculiarities you should fix;
- Your key values are actually strings. If you want numbers you can increment, you should use numbers from the beginning. If you store a string and increment it with the syntax above, it'll be turned into an integer.
- Arrays store string or a numbers as keys. You're using both. "01" will be stored as a string key, "10" will be stored as a number. Consider storing only numbers as keys.
None of these make your script not work, but the inconsistency and unnecessary performance hit are avoidable.
You can use a completely "functional" approach, even if it's PHP and even id its not very beautiful ;-) But it works (PHP >= 5.3.0):
...
$fr = 1; $to = 23;
# generate original Array
$hourly = array_combine(
array_map( function($n){return sprintf("%02s",$n);}, range($fr,$to) ), # Keys
array_map( function($n){return 0;}, range($fr,$to) ) # Values
);
$updates = Array('01','03','21','01','22');
# update values based on keys found in $updates
array_walk( $updates, function($u){global $hourly; $hourly[$u]++;} );
...
Regards
rbo
You could construct an array with the updated info ($new = array('01' => '02','03' => '01',)
etc and then use array_replace($hourly,$new)
or array_merge($hourly,$new)
. There are probably alternative functions too.
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 ));
精彩评论