Notice: Undefined index when trying to increment an associative array in PHP - php

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.

$newarray = array();
foreach ($array as $variable)
{
if (!isset($newarray[$variable])) {
$newarray[$variable] = 0;
}
$newarray[$variable]++;
}

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
)

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

<?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.

$newarray = array();
foreach ($array as $variable)
{
if(!isset($newarray[$variable]))
$newarray[$variable] = 0;
$newarray[$variable]++;
var_dump($newarray);
}

You are incrementing the wrong thing, try this instead:
foreach ($array as $key => $variable) {
$array[$key]++;
var_dump($array);
}

Related

How to keep only empty elements in array in php?

I have one array and i want to keep only blank values in array in php so how can i achieve that ?
My array is like
$array = array(0=>5,1=>6,2=>7,3=>'',4=>'');
so in result array
$array = array(3=>'',4=>'');
I want like this with existing keys.
You can use array_filter.
function isBlank($arrayValue): bool
{
return '' === $arrayValue;
}
$array = array(0 => 5, 1 => 6, 2 => 7, 3 => '', 4 => '');
var_dump(array_filter($array, 'isBlank'));
use for each loop like this
foreach($array as $x=>$value)
if($value=="")
{
$save=array($x=>$value)
}
if you want print then use print_r in loop
there is likely a fancy built in function but I would:
foreach($arry as $k=>$v){
if($v != ''){
unset($arry[$k]);
}
}
the problem is; you are not using an associative array so I am pretty sure the resulting values would be (from your example) $array = array(0=>'',1=>''); so you would need to:
$newArry = array();
foreach($arry as $k=>$v){
if($v == ''){
$newArry[$k] = $v;
}
}

PHP Pass by reference error after using same var

Take a look to this code, and help me to understand the result
$x = array('hello', 'beautiful', 'world');
$y = array('bye bye','world', 'harsh');
foreach ($x as $n => &$v) { }
$v = "DONT CHANGE!";
foreach ($y as $n => $v){ }
print_r($x);
die;
It prints:
Array
(
[0] => hello
[1] => beautiful
[2] => harsh
)
Why it changes the LAST element of the $x? it just dont follow any logic!
After this loop is executed:
foreach ($x as $n => &$v) { }
$v ends up as a reference to $x[2]. Whatever you assign to $v actually gets assigned $x[2]. So at each iteration of the second loop:
foreach ($y as $n => $v) { }
$v (or should I say $x[2]) becomes:
'bye bye'
'world'
'harsh'
// ...
$v = "DONT CHANGE!";
unset($v);
// ...
because $v is still a reference, which later takes the last item in the last foreach loop.
EDIT: See the reference where it reads (in a code block)
unset($value); // break the reference with the last element
Foreach loops are not functions.An ampersand(&) at foreach does not work to preserve the values like at functions.
So even if you have $var in the second foreach () do not expect it to be like a "ghost" out of the loop.

Can PHP's list() work with associative arrays?

Example:
list($fruit1, $fruit2) = array('apples', 'oranges');
code above of course works ok, but code below:
list($fruit1, $fruit2) = array('fruit1' => 'apples', 'fruit2' => 'oranges');
gives: Notice: Undefined offset: 1 in....
Is there any way to refer to named keys somehow with list like list('fruit1' : $fruit1), have you seen anything like this planned for future release?
With/from PHP 7.1:
For keyed arrays;
$array = ['fruit1' => 'apple', 'fruit2' => 'orange'];
// [] style
['fruit1' => $fruit1, 'fruit2' => $fruit2] = $array;
// list() style
list('fruit1' => $fruit1, 'fruit2' => $fruit2) = $array;
echo $fruit1; // apple
For unkeyed arrays;
$array = ['apple', 'orange'];
// [] style
[$fruit1, $fruit2] = $array;
// list() style
list($fruit1, $fruit2) = $array;
echo $fruit1; // apple
Note: use [] style if possible by version, maybe list goes a new type in the future, who knows...
EDIT: This approach was useful back in the day (it was asked & answered nine years ago), but see Kerem's answer below for a better approach with newer PHP 7+ syntax.
Try the extract() function. It will create variables of all your keys, assigned to their associated values:
extract(array('fruit1' => 'apples', 'fruit2' => 'oranges'));
var_dump($fruit1);
var_dump($fruit2);
What about using array_values()?
<?php
list($fruit1, $fruit2) = array_values( array('fruit1'=>'apples','fruit2'=>'oranges') );
?>
It's pretty straightforward to implement.
function orderedValuesArray(array &$associativeArray, array $keys, $missingKeyDefault = null)
{
$result = [];
foreach ($keys as &$key) {
if (!array_key_exists($key, $associativeArray)) {
$result[] = $missingKeyDefault;
} else {
$result[] = $associativeArray[$key];
}
}
return $result;
}
$arr = [
'a' => 1,
'b' => 2,
'c' => 3
];
list($a, $b, $c) = orderedValuesArray($arr, ['a','AAA', 'c', 'b']);
echo $a, ', ', $b, ', ', $c, PHP_EOL;
output: 1, , 3
less typing on usage side
no elements order dependency (unlike array_values)
direct control over variables names (unlike extract) - smaller name collision risk, better IDE support
If you are in my case:
list() only works on numerical array. So if you can, leaving blank in fetch() or fetchAll() -> let it have 2 options: numerical array and associative array. It will work.
consider this an elegant solution:
<?php
$fruits = array('fruit1'=> 'apples','fruit2'=>'oranges');
foreach ($fruits as $key => $value)
{
$$key = $value;
}
echo $fruit1; //=apples
?>
<?php
function array_list($array)
{
foreach($array as $key => $value)
$GLOBALS[$key] = $value;
}
$array = array('fruit2'=>'apples','fruit1'=>'oranges');
array_list($array);
echo $fruit1; // oranges
?>

Reset/remove all values in an array in PHP

I have an array_flipped array that looks something like:
{ "a" => 0, "b" => 1, "c" => 2 }
Is there a standard function that I can use so it looks like (where all the values are set to 0?):
{ "a" => 0, "b" => 0, "c" => 0 }
I tried using a foreach loop, but if I remember correctly from other programming languages, you shouldn't be able to change the value of an array via a foreach loop.
foreach( $poll_options as $k => $v )
$v = 0; // doesn't seem to work...
tl; dr: how can I set all the values of an array to 0? Is there a standard function to do this?
$array = array_fill_keys(array_keys($array), 0);
or
array_walk($array, create_function('&$a', '$a = 0;'));
You can use a foreach to reset the values;
foreach($poll_options as $k => $v) {
$poll_options[$k] = 0;
}
array_fill_keys function is easiest one for me to clear the array. Just use like
array_fill_keys(array_keys($array), "")
or
array_fill_keys(array_keys($array), whatever you want to do)
foreach may cause to decrease your performance to be sure that which one is your actual need.
Run your loop like this, it will work:
foreach( $poll_options as $k => $v )
$poll_options[$k] = 0;
Moreover, ideally you should not be able to change the structure of the array while using foreach, but changing the values does no harm.
As of PHP 5.3 you can use lambda functions, so here's a functional solution:
$array = array_map(function($v){ return 0; }, $array);
You have to use an ampersand...
foreach( $poll_options as &$v)
$v = 0;
Or just use a for loop.
you can try this
foreach( $poll_options as $k => &$v )
$v = 0;
Address of $v
array_combine(array_keys($array), array_fill(0, count($array), 0))
Would be the least manual way of doing it.
There are two types for variable assignment in PHP,
Copy
Reference
In reference assignment, ( $a = &$b ), $a and $b both, refers to the same content. ( read manual )
So, if you want to change the array in thesame time as you doing foreach on it, there are two ways :
1- Making a copy of array :
foreach($array as $key=>$value){
$array[$key] = 0 ; // reassign the array's value
}
2 - By reference:
foreach($array as $key => &$value){
$value = 0 ;
}

Understanding Arrays as part of the foreach in php

Having:
$a as $key => $value;
is the same as having:
$a=array();
?
No, it's not. It's more like
list($key, $value) = each($arr);
See the manual
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br />\n";
}
is identical to
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
echo "Key: $key; Value: $value<br />\n";
}
Also see
The while Control Structure
list — Assign variables as if they were an array
each — Return the current key and value pair from an array and advance the array cursor
reset — Set the internal pointer of an array to its first element
First of all it has to say
foreach($a as $key => $value)
Then, as far as I know,
foreach($a = array())
doesn't compile.
That said, if you foreach, you iterate through the elements of an array. With the 'as' keyword, you get pairs of key/value for each element, where $key would be the index by which you can get $value:
$value = $a[$key];
Did this answer your question? If not, please specify.
edit:
In other programming languages it would spell something like
foreach($key => $value in $a)
or (C#)
foreach(KeyValuePair<type1, type2> kv in a)
which I think is more intuitive, but basically the same.
if you have the following:
$a = array('foo' => array('element1', 'element2'), 'bar' => array('sub1', 'sub2'));
if you use $a as $key=> $value in the foreach loop,
$key will be 'foo', and $value will be array('element1', 'element2') in the first iteration, in the second $key == 'bar' and $value == array('sub1', 'sub2').
If you loop over an array using foreach, the array is the first expression inside the parenthesis.
It can be a variable, like $a, or an array literal like array(1, 2, 3). The following loops are identical:
With an array literal:
foreach(array(1, 2, 3) as $number)
print($number);
With a variable:
$a = array(1, 2, 3);
foreach($a as $number)
print($number);

Categories