Issue with passing values by reference into an array - php

I have an array named $initValues, which contains strings or numeric values and using a foreach loop I want to transfer the values to the $values array and the type of each value to $types.
Code:
$initValues = ["1-2", "2-1"];
$values = [];
$types = [];
foreach ($initValues as $value) {
$values[] = &$value; # by reference.
$types[] = gettype($value);
}
As you can see in the above code, I'm inserting the value by reference in $values, which is required by a function used later on, so that can't be changed. When I execute the above code and show the result using var_dump($values), I get the following:
array(2) { [0]=> &string(3) "2-1" [1]=> &string(3) "2-1" }
The problem with the above result is that essentially both elements of my $values array are the last element of $initValues and not both as in the desired result, which is:
array(2) { [0]=> &string(3) "1-2" [1]=> &string(3) "2-1" }
If I enter each value by value into the array the result is correct, but I'm facing a problem later on, so that's not an option. How can I modify my code, in order to produce the desired result?

Use an index in your foreach loop.
This should work:
$initValues = ["1-2", "2-1"];
$values = [];
$types = [];
foreach ($initValues as $ix=>$value) {
$values[] = &$initValues[$ix];
$types[] = gettype($value);
}
var_dump($values);

Related

Convert single array into multidimensional array in PHP?

If I have this array in PHP:
array(3) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
}
How can I convert this single array into a multidimensional array? What is the quickest way? So I can access this array like:
$array["first"]["second"]...
I want to be able to then set a value to this index like:
$array["first"]["second"]["third"] = "example";
I thought that I need a for loop or a recursive function but I have no idea how to start.
It wasn't quite as simple as I had imagined to begin with. The key to it was doing the process backwards - starting with the last array and then wrapping it in more arrays until you get back to the top level.
$array = array("first", "second", "third");
$newArr = array();
//loop backwards from the last element
for ($i = count($array)-1; $i >= 0 ; $i--)
{
$arr = array();
if ($i == count($array)-1) {
$val = "example";
$arr[$array[$i]] = $val;
}
else {
$arr[$array[$i]] = $newArr;
}
$newArr = $arr;
}
var_dump($newArr);
echo "-------".PHP_EOL;
echo $newArr["first"]["second"]["third"];
Demo: http://sandbox.onlinephpfunctions.com/code/0d7fa30fde7126160fbcc0e80e5727f17b19e39f

Php group repeated array values

How to group repeated array values in an array using PHP?
I have an array like this
array[0]=203,
array[1]=204,
array[2]=204,
array[3]=203,
array[4]=203,
array[5]=205
I need results like
[203]=1,
[204]=2,
[203]=2,
[205]=1
i want the count of continuously repeating array values
One option to your expected output is to create a indexed array with the associative array below it.
This will create this kind of array:
array(4) {
[0]=>
array(1) {
[203]=>
int(1)
}
[1]=>
array(1) {
[204]=>
int(2)
}
[2]=>
array(1) {
[203]=>
int(2)
}
[3]=>
array(1) {
[205]=>
int(1)
}
}
This is not what you wanted but it is what is possible.
The code loops and keeps track of what the previous value is, if it's the same it will count up the value, else create a new indexed and associative array with value 1.
$array =[203,204,204,203,203,205];
$i=-1;
$prev = null;
$new=[];
foreach($array as $val){
if($val != $prev){
$i++;
}
if(!isset($new[$i][$val])){
$new[$i][$val] =1;
}else{
$new[$i][$val]++;
}
$prev = $val;
}
var_dump($new);
https://3v4l.org/W2adN
array[0]=203;
array[1]=204;
array[2]=204;
array[3]=203;
array[4]=203;
array[5]=205;
$new_array = array();
foreach ($array as $key => $value) {
if(empty($new_array[$value])){
$new_array[$value] = 1;
}else{
$new_array[$value]++;
}
}
/*Now in the array $new_array you have the count of continuously repeating array values*/
This can be done in one line of code using array_count_value function in php.
$arr[0]=203;
$arr[1]=204;
$arr[2]=204;
$arr[3]=203;
$arr[4]=203;
$arr[5]=205;
$result = array_count_values( $arr );
var_dump( $result );
output
array (size=3)
203 => int 3
204 => int 2
205 => int 1

Split array based on value for a single dimentional array with key and value

I am trying to split an array to different arrays based on values.
This is my array
$myArray=('x'=>'europe','y'=>'europe','a'=>'USA','b'=>'USA','c'=>'Canada');
I want to split the array based on value like below
$newList[europe]=(x,y);
$newList[USA]=(a,b);
$newLsit[Canada]=(c);
I tried the following
foreach($myArray as $key =>$value){
$myList[$value]=$key;
}
and
foreach($myArray as $key => $value){
echo $key;
if($value=='USA')$myList['USA']=$key;
if($value=='europe')$myList['europe']=$key;
if($value=='Canada')$myList['Canada']=$key;
}
the output is the same
Array ( [europe] => y [USA] => b [Canada] => c )
I do not understand what the issue could be. Any help is much appriciated.
If you have more countries, then if loop is not a good method. Instead of that you can create array for each country using foreach statement. Please see the below code, it may help you.
$myArray = array('x'=>'europe','y'=>'europe','a'=>'USA','b'=>'USA','c'=>'Canada');
$new_array = array();
foreach($myArray as $key=>$val)
{
$new_array[$val][] = $key;
}
print_r($new_array);
A simple way.
$myArray= array('x'=>'europe','y'=>'europe','a'=>'USA','b'=>'USA','c'=>'Canada');
$grouped = array();
foreach ($myArray as $key => $group) {
$grouped[$group][] = $key;
}
print_r($grouped);
DEMO http://phpio.net/s/9lw
you need to use this
$myList = array();
foreach($myArray as $key => $value)
{
if($value=='USA') $myList['USA'][]=$key;
if($value=='europe') $myList['europe'][]=$key;
if($value=='Canada') $myList['Canada'][]=$key;
}
An array can not have same key multiple times. So in look the key is being overwritten by the latest value. You need to save the array in nested way.
$myArray= array('x'=>'europe','y'=>'europe','a'=>'USA','b'=>'USA','c'=>'Canada');
foreach($myArray as $key => $value) {
// Value as the key & key in sub array
$new[$value][] = $key;
}
var_dump($new);
Output
array(3) {
["europe"]=>
array(2) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
}
["USA"]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
}
["Canada"]=>
array(1) {
[0]=>
string(1) "c"
}
}
You need to push array when exists and assign when not present- This will godd for any warning. Use the array_key_exists() function to check the value is in the array as key or not??
$myArray = array('x'=>'europe','y'=>'europe','a'=>'USA','b'=>'USA','c'=>'Canada');
$newList = array();
foreach($myArray as $key => $value){
if(array_key_exists($value, $newList))
array_push($newList[$value], $key);
else
$newList[$value][] = $key;
}
print_r($newList);
Online Example

Changing values of multidimensional array php

Its my first time working with multidimensional arrays in php. I need to change the second number in each sub array.
What I want is to check if the Id in the array matches the Id from the database. When the two match I want to change the 2nd entry in the sub array by adding a number to it. If the Id from the query does not match anything in the list I want a new sub array to be pushed to the end of the array with the values of Id and points_description.
Also, if its helpful, my program right now does find the matches. The only thing is, it does not update the 2D array.
$array = array(array());
while ($row_description = mysqli_fetch_array($query_description)) {
$check = 1;
$is_match = 0;
foreach ($array as $i) {
foreach ($i as $value) {
if ($check == 1) {
if ($row_description['Id'] == $value) {
//$array[$i] += $points_description;
$is_match = 1;
}
}
$check++;
$check %= 2; //toggle between check and points
}
}
if ($is_match == 0) {
array_push($array, array($row_description['Id'], $points_description));
}
}
I feel like Im doing this so wrong. I just want to go through my 2D array and change every second value. The expected output should be a print out of all the Ids and their corresponding point value
I hope this is helpful enough.
Example: $row_description['Id'] = 2 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1))
if $row_description['Id'] = 3 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1),array(3,3))
By default PHP will copy an array when you use it in a foreach.
To prevent PHP from creating this copy you need to use to reference the value with &
Simple example :
<?php
$arrFoo = [1, 2, 3, 4, 5,];
$arrBar = [3, 6, 9,];
Default PHP behavior : Make a copy
foreach($arrFoo as $value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
*/
ByReference : Don't create the copy :
foreach($arrFoo as &$value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(162)
[1]=>
int(324)
[2]=>
int(486)
[3]=>
int(648)
[4]=>
&int(810)
}
*/

How do I check to see if array slot is empty?

In the example below $list is an array created by user input earlier in the code, and some slots the user has input nothing. I want to skip the empty items, so the commas aren't created in the output.
$list = array("first", "second", "", "", "fifth", "sixth", "", "");
foreach ($list as $each){$places .= $each . ",";}
results
first,second,,,fifth,sixth,,,
result I want
first,second,fifth,sixth
Got a solution. It looks like this:
$list = array_filter($list);
$places .= implode (",",$list);
To ignore the empty values, you can use
$list = array_filter($list);
Results
Array
(
[0] => first
[1] => second
[4] => fifth
[5] => sixth
)
Source: Mark
array_filter, when passed no second parameter, will remove any empty entries. From there you can proceed as normal:
foreach (array_filter($list) as $each){
$places .= $each . ',';
}
Though you can also use implode if you're just turning it in to a CSV:
$places .= implode(',', array_filter($list));
Side Note Though in this case array_filter may work, it is worth noting that this removes entries that result in a "falsy" result. That is to say:
$list = array_filter(array('foo','0','false',''));
// Result:
// array(2) {
// [0]=>
// string(3) "foo"
// [2]=>
// string(5) "false"
// }
So be careful. If the user could potentially be entering in numbers, I would stick with comparing empty. Alternatively you can use the second parameter of array_filter to make it more explicit:
function nonEmptyEntries($e)
{
return ((string)$e) !== '';
}
$list = array_filter($list, 'nonEmptyEntries');
// result:
//array(3) {
// [0]=>
// string(3) "foo"
// [1]=>
// string(1) "0"
// [2]=>
// string(5) "false"
//}
(Note that the 0 entry is kept, which differs from a blanket array_filter)

Categories