Trying to loop through array and reassign value - php

I have two arrays, both with the same indexes. What I want to do is loop through one of the arrays (portConfigArray), and change the value of an existing item by using data from a second array. (portStatusArray)
Here's the logic:
$i=0;
foreach ($portConfigArray as $configentry)
{
$configentry['LinkState'] = $portStatusArray[$i]['LinkState'];
$i = $i + 1;
echo $configentry['LinkState'];
}
$portdetailsArray = $portConfigArray;
var_dump($portdetailsArray);
the echo statement shows the correct values being assigned for each item in the portConfigArray. (its just a string value like "Up" or "Down")
But in the var_dump I can see that the value hasn't been updated correctly. It shows
["LinkState"]=> string(0) ""
as the output for each record.
Can you tell me what I'm doing wrong?

You need to make $configentry a reference, otherwise it's just a copy
foreach ($portConfigArray as &$configentry)

foreach ($portConfigArray as $configentry)
Should be
foreach ($portConfigArray as &$configentry)
Essentially this means the loop deals with the actual value rather than a copy of it.

While you can make $configentry a reference, as stated in other answers, it CAN cause major issues if you reuse such "referenced" variables later on in the script for other purposes. A safer method is to use the key=>val version of foreach, and directly modify the array:
foreach($portConfigArray as $key => $configentry) {
$portConfigArray[$key] = 'newvalue';
}
The reference version can cause issues, e.g.
php > $a = array('a', 'b', 'c');
php > foreach($a as &$val) { $val++; };
php > print_r($a);
Array
(
[0] => b
[1] => c
[2] => d
)
php > $b = array('p', 'q', 'r');
php > foreach($b as $val) { $val++; }; <--note, $val, not &$val
php > print_r($b);
Array
(
[0] => p <---hey, these 3 didn't change!
[1] => q
[2] => r
)
php > print_r($a);
Array
(
[0] => b
[1] => c
[2] => s <---uh-oh!
)
php >

Related

Create 2-element rows from flat array where the every second row value is also the first value of the next row

$arrayinput = array("a", "b", "c", "d", "e");
How can I achieve the following output....
output:
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => b
[1] => c
)
[2] => Array
(
[0] => c
[1] => d
)
[3] => Array
(
[0] => d
[1] => e
)
[4] => Array
(
[0] => e
)
)
You can use this, live demo here.
<?php
$arrayinput = array("a","b","c","d","e");
$array = [];
foreach($arrayinput as $v)
{
$arr = [];
$arr[] = $v;
if($next = next($arrayinput))
$arr[] = $next;
$array[] = $arr;
}
print_r($array);
live example here: http://sandbox.onlinephpfunctions.com/code/4de9dda457de92abdee6b4aec83b3ccff680334e
$arrayinput = array("a","b","c","d","e");
$result = [];
for ($x = 0; $x < count($arrayinput); $x+=2 ) {
$tmp = [];
$tmp[] = $arrayinput[$x];
if ($x+1 < count($arrayinput)) $tmp[] = $arrayinput[$x+1];
$result[] = $tmp;
}
var_dump($result);
By declaring single-use reference variables, you don't need to call next() -- which is not falsey-safe and there is a warning in the php manual. You also won't need to keep track of the previous index or make iterated calls of count().
For all iterations except for the first one (because there is no previous value), push the current value into the previous subarray as the second element. After pushing the second value, "disconnect" the reference variable so that the same process can be repeated on subsequent iterations. This is how I'd do it in my own project.
Code: (Demo)
$result = [];
foreach (range('a', 'e') as $value) {
if ($result) {
$row[] = $value;
unset($row);
}
$row = [$value];
$result[] = &$row;
}
var_export($result);
If you always want to have 2 elements in each subarray and you want to pad with null on the final iteration, you could use a transposing technique and send a copy of the input array (less the first element) as an additional argument. This is a much more concise technique (one-liner) (Demo)
var_export(array_map(null, $array, array_slice($array, 1)));

Edit array placement

I am having a simple issue with ordering an array elements.
Let's assume we have an array like this
[0]=>zero
[1]=>one
[2]=>two
[3]=>three
What i want is a way to move some elements to first position for example move one and two to first positions so i will have:
[1]=>one
[2]=>two
[0]=>zero
[3]=>three
and this should be done without knowing the current position of the element in the array which means it should be done by specifying the name of wanted element to move.
I thought about array_splice() but it won't work since i should specify the key of the element in array.
You could build two arrays (one with the searched values and one without) and merge them. Keep in mind that if you want to keep numeric keys, you should use the + operator instead of array_merge :
<?php
$array = array('zero', 'one', 'two', 'three');
$searched_values = array('one', 'two');
$array_first = $array_second = array();
foreach ($array as $key=>$value) {
if (in_array($value, $searched_values))
$array_first[$key] = $value;
else
$array_second[$key] = $value;
}
$array_end = $array_first + $array_second;
echo '<pre>'; print_r($array_end); echo '</pre>';
Returns :
Array
(
[1] => one
[2] => two
[0] => zero
[3] => three
)
EDIT : Keeping the $searched_values order
In this case, you just need to loop over the serached values in order to build an array of found values and simultaneously delete the initial array's entry :
<?php
$array = array('zero', 'one', 'two', 'three');
$searched_values = array('one', 'three', 'two');
$array_found = array();
foreach ($searched_values as $key=>$value) {
$found_key = array_search($value, $array);
if ($found_key !== false) {
$array_found[$found_key] = $value;
unset($array[$found_key]);
}
}
$array_end = $array_found + $array;
echo '<pre>'; print_r($array_end); echo '</pre>';
?>
Returns :
Array
(
[1] => one
[3] => three
[2] => two
[0] => zero
)
The only way I can think to do this is to remove it then add it:
$key = array_search('one', $array); // $key = 1;
$v = $my_array[$key];
unset($my_array[$key]);
array_unshift($my_array, $v);
Output:
[0] => one
[1] => zero
[2] => two
[3] => three
UPDATE:
If you use array_unshift it will not override your current element.

How to skip iteration in foreach inside foreach

I have an array of values, and i want to insert the values to another array but with an if condition, if the "if" is true I want to skip the iteration.
Code:
$array=array(array(1=>11,2=>22,3=>23,4=>44,5=>55));
$insert=array();
foreach($array as $k1=>$v1)
{
foreach($v1 as $k2=>$v2)
{
if($v2==23)
{
break;
}
}
$insert[]=$v1;
}
final result should look like that
Array
(
[0] => Array
(
[1] => 11
[2] => 22
[3] => 44
[4] => 55
)
)
I tried using: break,return,continue...
Thanks
There are a few ways to do this. You can loop over the outer array and use array_filter on the inner array to remove where the value is 23 like this (IMO preferred; this also uses an array of $dontWant numbers so it is easier to add or change numbers later):
<?php
$array = array(array(1=>11,2=>22,3=>23,4=>44,5=>55));
$insert = array();
//array of numbers you don't want
$dontWant = array(23);
//loop over outer array
foreach($array as $subArray){
//add to $insert a filtered array
//subArray is filtered to remove where value is in $dontWant
$insert[] = array_filter($subArray, function($val) uses ($dontWant) {
//returns true if the value is not in the array of numbers we dont want
return !in_array($val, $dontWant);
});
}
//display final array
echo '<pre>'.print_r($insert,1).'</pre>';
Or you can reference the first key to add to a sub array in $insert like (which is a little more like what your code is trying to do and show that you are not too far off):
<?php
$array = array(array(1=>11,2=>22,3=>23,4=>44,5=>55));
$insert = array();
//loop over outer array
foreach($array as $k1=>$v1){
//add an empty array to $insert
$insert[$k1] = array();
//loop over inner array
foreach($v1 as $k2=>$v2){
//if the inner array value is not 23
if($v2 != 23){
//add to inner array in insert
$insert[$k1][] = $v2;
}
}
}
//display the result
echo '<pre>'.print_r($insert,1).'</pre>';
Both of these methods would produce the same result. IMO using array_filter is the preferred method, but the second method might be a little easier to understand for someone new to programming.
Why don't you just try it like this?
foreach($v1 as $k2=>$v2)
{
if($v2!=23)
{
$insert[]=$v2;
}
}
EDIT:
Explanation: You check with the if($v2!=23) if the value of the variable $v2 is not equal to (that is the != sign) any given number that stands after the inequality operator, and if so, it will insert that value to the array $insert.
I hope it is clear now.
Sorry, I've written $v1 instead of $v2, the code should work now.
To add variants :)
$array=array(array(1=>11,2=>22,3=>23,4=>44,5=>55));
$insert=array();
foreach($array as $a)
{
while (($i = array_search(23, $a)) !== false)
{ unset($a[$i]); sort($a); }
$insert[] = $a;
}
print_r($a);
result:
Array ( [0] => Array ( [0] => 11 [1] => 22 [2] => 44 [3] => 55 ) )

PHP Pass By Refernce logic explanation [duplicate]

This question already has an answer here:
Why php iteration by reference returns a duplicate last record?
(1 answer)
Closed 8 years ago.
Can anyone explain me the output of the following PHP script:
$a = array ('zero','one','two');
foreach ($a as &$v) {
}
foreach ($a as $v) {
}
print_r($a);
Output:
Array
(
[0] => zero
[1] => one
[2] => one
)
Not really an answer, but it may help you understand what's going on.
<?php
$a = array ('zero','one','two');
foreach ($a as &$v) {
}
print_r($v); // two
$v = "four";
print_r($a);
// Array
// (
// [0] => zero
// [1] => one
// [2] => four
// )
Passing by reference, you can change value inside or outside loop.
<?php
$a = array ('zero','one','two');
foreach ($a as &$v) {
}
// before loop $v is reference to last item in array $a
// if you perform unset($v) before this loop, nothing will change in $a
foreach ($a as $v) {
// here you assigning $v values from this array in loop
}
print_r($a);
// Array
// (
// [0] => zero
// [1] => one
// [2] => one
// )

Access newly added key=>value in associative array during loop

I am trying to add a key=>value pair to an array while using a foreach loop, when that value is added the foreach loop needs to process the new key=>value pair.
$array = array(
'one' => 1,
'two' => 2,
'three' => 3
);
foreach($array as $key => $value) {
if ($key == 'three') {
$array['four'] = 4;
} else if ($key == 'four') {
$array['five'] = 5;
}
}
If I print the array after the loop, I would expect to see all 5 kv's, but instead I only see this:
Array
(
[one] => 1
[two] => 2
[three] => 3
[four] => 4
)
Is there some way, when I add the fourth pair, to actually process it so the fifth pair gets added within that foreach loop (or another kind of loop?)
According to php documentation,
As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior.
You cannot modify the array during foreach. However, an user posted an example of a regular while loop that does what you need: http://www.php.net/manual/en/control-structures.foreach.php#99909
I report it here
<?php
$values = array(1 => 'a', 2 => 'b', 3 => 'c');
while (list($key, $value) = each($values)) {
echo "$key => $value \r\n";
if ($key == 3) {
$values[4] = 'd';
}
if ($key == 4) {
$values[5] = 'e';
}
}
?>
the code above will output:
1 => a
2 => b
3 => c
4 => d
5 => e
That's because PHP will internally use it's own copy of the array pointer. You are iterating trough it's orginal key/values not through the modified array.
As the original array contains the key three, the first if statement will match, but not the second
Another simpler example is the fact, that this is not an infinite loop:
$array = array(1);
foreach($array as $val) {
$array []= $val +1;
}
var_dump($array);
Output:
array(2) {
[0] =>
int(1)
[1] =>
int(2)
}
However, the PHP documentation says not much to that:
As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior.

Categories