Reputation: 3415
I'm trying to increment the value for $variable each time a duplicate variable occurs. I'm not sure if this is syntactically correct, but I think this is semantically correct. var_dump seems to spit out the correct outputs, but i get this error: Notice: Undefined index...
$newarray = array();
foreach ($array as $variable)
{
$newarray[$variable]++;
var_dump($newarray);
}
$array = (0 => h, 1 => e, 2 => l, 3=> l, 4=> o);
goal:
'h' => int 1
'e' => int 1
'l' => int 2
'o' => int 1
My code works, it's just that I get some weird NOTICE.
Upvotes: 5
Views: 8103
Reputation: 31
This takes advantage of the fact that references accept undefined variables and PHP silently creates them:
$_ = &$lookup_with_long_name[$key_with_long_name] xor $_ += $value_with_long_name;
This only uses the lookup, key, and value variables once each, and sets if undefined and increments if defined, all without throwing a warning (or eventually an error in PHP 9)
xor operator works because PHP always has to evaluate both sides.
Make sure to unset($_) when you're done.
Upvotes: 0
Reputation: 9773
I really like mickmackusa's use of null coalesce in
$new = [];
foreach ($array as $v) {
$new[$v] ??= 0;
++$new[$v];
}
but you can save the second lookup using an array element reference which automatically inserts a null
element if not present:
$new = [];
foreach ($array as $v) {
$entry =& $new[$v];
++$entry;
}
Luckily, the increment operator considers null
to be zero and increments to 1 as desired.
Upvotes: 0
Reputation: 47894
In modern PHP, you can avoid the isset()
call by leveraging the null coalescing operator. In the snippet below, the technique sets the variable to 0 if the variable is not yet declared. Then you can freely use a range of shorthand manipulations such as concatenation, arithmetic, etc.
$new = [];
foreach ($array as $v) {
$new[$v] = ($new[$v] ?? 0) + 1;
}
Or if you want to continue using ++
, then you can use the "null coalescing assignment operator". The logic on the right side of assignment is not even executed if the variable is already declared. The below snippet will perform identically to the above snippet.
$new = [];
foreach ($array as $v) {
$new[$v] ??= 0;
++$new[$v];
}
As for your sample data and desired result of letters and counts, I'd probably use a fully native, functional approach. (Demo)
var_export(
array_count_values(str_split('hello'))
); // letters are in the same order as they were encountered
Much less attractive technique for the same result:
$assoc = count_chars('hello', 1);
var_export(
array_reduce(
array_keys($assoc),
fn($result, $k) => $result += [chr($k) => $assoc[$k]],
[]
)
); // letters are alphabetized
Upvotes: 3
Reputation: 157863
$newarray = array();
foreach ($array as $variable)
{
if (!isset($newarray[$variable])) {
$newarray[$variable] = 0;
}
$newarray[$variable]++;
}
Upvotes: 10
Reputation: 92581
$newarray = array();
foreach ($array as $variable)
{
if(!isset($newarray[$variable]))
$newarray[$variable] = 0;
$newarray[$variable]++;
var_dump($newarray);
}
Upvotes: 0
Reputation: 96159
<?php
$newarray = array();
foreach ($array as $variable) {
if ( !array_key_exists($variable, $newarray) ) {
$newarray[$variable] = 0;
}
++$newarray[$variable];
}
var_dump($newarray);
But you could also use array_count_values() instead.
Upvotes: 1
Reputation: 455030
Take a look at the function array_count_values(). It does exactly what you are trying to do.
Sample from php.net:
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
Result:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)
Upvotes: 3
Reputation: 2369
You are incrementing the wrong thing, try this instead:
foreach ($array as $key => $variable) {
$array[$key]++;
var_dump($array);
}
Upvotes: -2