PHP Array & Pointer Confusion - php

Let's say I have a function like this:
function z($zzz){
for($c=0;$c<5;$c++){
$zzz[$c]= 10;
//more and more codes
}
}
I want to write a loop so that
the 1st time the function is executed, argument $array is passed
the 2nd time : argument $array[0] is passed
while the 3rd time : argument $array[1] is passed
.....
and the 12th time : argument $array[0][0] is passed
This is what comes to my mind:
$a = -1;
$b = -1;
$array = array();
while($a<10){
while($b<10){
z($array);
$b++;
$array= &$array[$b];
}
$a++;
$array= &$array[$a];
}
I've tried it but it didn't work..
I would appreciate if someone can provide a solution..

If z() is supposed to change the passed array, your function definition should be:
function z(&$zzz)

$a = 0;
while ($a < 99) // <-- edit as applicable
{
$b = 0
while ($b < 12)
{
if ($b == 0)
{
Z($array[$a]);
} else
{
Z($array[$a][$b]);
}
$b++;
}
$a++;
}
And as stated by Jack you need to pass the $array variable by reference for update. Not too sure what that function is trying to achieve though. If you need to fill an array with a predermined dimension, maybe array_fill could be more useful.
http://www.php.net/manual/en/function.array-fill.php
function z(&$zzz){
for($c=0;$c<5;$c++){
$zzz[$c]= 10;
//more and more codes
}
}

Related

I need to check the arrays having same objects or more than same in php

I have variable in php , first is $needed and second is $whatwehave so the objects in arrays is like that =>
$needed=['name','family','job'];
$whatwehave=['name','family','job'];
The thing that i want is available using for but I am looking for a better way.
The thing that i want is checking if the needed arrays exist in $whatwehave say 0 and if its not exist say 1 and if you don't know what is the needed array its stacked in $needed its very simple and i think there is a code in PHP for doing this like in_array($array1,$array2) or something else
My way is this :
$error=0;
for($i=0;$i<=(count($needed)-1);$i++){
if(!in_array($needed[$i],$whatwehave)){
$error=1;
}
}
echo $error;
The way that i looking for is something like that:
if(in_array($first_array,$second_array)){echo 0;}else{echo 1;}
Use function array_diff()
echo array_diff($needed, $whatwehave) ? 1 : 0;
https://www.php.net/manual/ru/function.array-diff.php
<?php
function check_similar($actual, $expected) {
if(!is_array($actual) && !is_array($expected))
return false;
$minLength = count($actual);
if(count($expected) < $minLength)
$minLength = count($expected);
$index = 0;
foreach($actual as $arr) {
if(in_array($arr, $expected))
$index++;
}
if($index >= $minLength)
return true;
return false;
}
$arr1 = ['1','2','3'];
$arr2 = ['1','2','3','4'];
var_dump(check_similar($arr1, $arr2));

Finding max value in array using recursion in PHP

I know how to use loop to do this simple problem, but I want to play more with recursion. I trying to find max value in array using recursion with PHP. My basic idea is compare the first value of the array with the maximum value of the new array (made by remove the first value of the given array):
function find_max($arr)
{
if ($arr = [])
{
return 0; // base case
} else
{
if ($arr[0] > find_max(rest_of($arr)))
{
return $arr[0];
} else
{
return find_max(rest_of($arr));
}
}
}
function rest_of($arr)
{
unset($arr[0]); // remove the first value of the array
$arr = array_values($arr); // re-index the array
return $arr;
}
But when I run, it seems that it has infinite loop. "Undefined offset: 0"
Can anyone help me?
The problem is because of your base condition here,
if($arr = []){ ...
= is an assignment operator, not comparison operator. What you need here is a comparison operator ==. So it should be,
if($arr == []){
Furthermore, you can change your base condition like this way,
if(count($arr) == 1){
return $arr[0]; // base case
}
So your find_max() function should be like this:
function find_max($arr){
if(count($arr) == 1){
return $arr[0]; // base case
}
if ($arr[0] > find_max(rest_of($arr))){
return $arr[0];
} else{
return find_max(rest_of($arr));
}
}

PHP each and static array declaration

So, I've written some rather convoluted 'functional' PHP code to perform folding on an array. Don't worry, I won't use it anywhere. The problem is, PHP's 'each' function only seems to go as far as the end of an array as it is statically (actually, see bottom) declared.
// declare some arrays to fold with
$six = array("_1_","_2_","_3_","_4_","_5_","_6_");
// note: $ns = range(0,100) won't work at all--lazy evaluation?
$ns = array(1,2,3,4,5,6,7,8);
$ns[8] = 9; // this item is included
// add ten more elements to $ns. each can't find these
for($i=0; $i<10; ++$i)
$ns[] = $i;
// create a copy to see if it fixes 'each' problem
$ms = $ns;
$ms[0] = 3; // Just making sure it's actually a copy
$f = function( $a, $b ) { return $a . $b; };
$pls = function( $a, $b ) { return $a + $b; };
function fold_tr( &$a, $f )
{
$g = function ( $accum, &$a, $f ) use (&$g)
{
list($dummy,$n) = each($a);
if($n)
{
return $g($f($accum,$n),$a,$f);
}
else
{
return $accum;
}
};
reset($a);
return $g( NULL, $a, $f );
}
echo "<p>".fold_tr( $six, $f )."</p>"; // as expected: _1__2__3__4__5__6_
echo "<p>".fold_tr( $ns, $pls )."</p>"; // 45 = sum(1..9)
echo "<p>".fold_tr( $ms, $pls )."</p>"; // 47 = 3 + sum(2..9)
I honestly have no clue how each maintains its state; it seems vestigial at best, since there are better (non-magical) mechanisms in the language for iterating through a list, but does anyone know why it would register items added to an array using $a[$index] = value but not '$a[] = value`? Thanks in advance any insight on this behavior.
Your loop is exiting early thanks to PHP's weak typing:
if($n)
{
return $g($f($accum,$n),$a,$f);
}
else
{
return $accum;
}
when $n is 0 (e.g. $ns[9]), the condition will fail and your loop will terminate. Fix with the following:
if($n !== null)

Getting output from a function that grabs numbers

I need to parse a number that has 3 s.f. and 2 d.p. (e.g. 2.34). The first two numbers (1st and 2nd s.f.) are then multiplied by 10. The second number stays as it is. Thus, for the example above, $a = 23 and $b = 4. I was able to get code similar to below to work when it was not a function but I would like to be able to incorporate the code into a function. I would like to be able to get the value $a and the value $b out of the function (separately if possible) but I am having problems doing this. Any help would be much appreciated.
$z = 1.63;
function getcoordinates($conv) {
$z = number_format($conv, 2);
$z = (string)$z;
$a = substr($z,0,3)*10;
$b = substr($z,3,1);
$a = settype($a, "float");
$b = settype($b, "float");
return $a;
return $b;
}
Why can’t you just calculate the values the way you described?
function getCoordinates($input) {
$a = floor($input * 10) % 100;
$b = floor($input * 100) % 10;
return array($a, $b);
}
As demonstrated here, you can use array() to return multiple values. When you call the function, you can use list() to put the values into separate variables:
list($a, $b) = getCoordinates(2.34);
echo "$a, $b\n"; // prints “23, 4”
Return an array.
return array($a, $b);
and, on the call site, receive the value with
list($a, $b) = getcoordinates(...);
function getcoordinates($conv) {
/* your code */
return array($a,$b);
}

Checking if array is multidimensional or not?

What is the most efficient way to check if an array is a flat array
of primitive values or if it is a multidimensional array?
Is there any way to do this without actually looping through an
array and running is_array() on each of its elements?
Use count() twice; one time in default mode and one time in recursive mode. If the values match, the array is not multidimensional, as a multidimensional array would have a higher recursive count.
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
This option second value mode was added in PHP 4.2.0. From the PHP Docs:
If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array. count() does not detect infinite recursion.
However this method does not detect array(array()).
The short answer is no you can't do it without at least looping implicitly if the 'second dimension' could be anywhere. If it has to be in the first item, you'd just do
is_array($arr[0]);
But, the most efficient general way I could find is to use a foreach loop on the array, shortcircuiting whenever a hit is found (at least the implicit loop is better than the straight for()):
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
$c = array(1 => 'a',2 => 'b','foo' => array(1,array(2)));
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
function is_multi2($a) {
foreach ($a as $v) {
if (is_array($v)) return true;
}
return false;
}
function is_multi3($a) {
$c = count($a);
for ($i=0;$i<$c;$i++) {
if (is_array($a[$i])) return true;
}
return false;
}
$iters = 500000;
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi($a);
is_multi($b);
is_multi($c);
}
$end = microtime(true);
echo "is_multi took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi2($a);
is_multi2($b);
is_multi2($c);
}
$end = microtime(true);
echo "is_multi2 took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi3($a);
is_multi3($b);
is_multi3($c);
}
$end = microtime(true);
echo "is_multi3 took ".($end-$time)." seconds in $iters times\n";
?>
$ php multi.php
is_multi took 7.53565130424 seconds in 500000 times
is_multi2 took 4.56964588165 seconds in 500000 times
is_multi3 took 9.01706600189 seconds in 500000 times
Implicit looping, but we can't shortcircuit as soon as a match is found...
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
var_dump(is_multi($a));
var_dump(is_multi($b));
?>
$ php multi.php
bool(true)
bool(false)
For PHP 4.2.0 or newer:
function is_multi($array) {
return (count($array) != count($array, 1));
}
I think this is the most straight forward way and it's state-of-the-art:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
After PHP 7 you could simply do:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
You could look check is_array() on the first element, under the assumption that if the first element of an array is an array, then the rest of them are too.
I think you will find that this function is the simplest, most efficient, and fastest way.
function isMultiArray($a){
foreach($a as $v) if(is_array($v)) return TRUE;
return FALSE;
}
You can test it like this:
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
echo isMultiArray($a) ? 'is multi':'is not multi';
echo '<br />';
echo isMultiArray($b) ? 'is multi':'is not multi';
Don't use COUNT_RECURSIVE
click this site for know why
use rsort and then use isset
function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
Even this works
is_array(current($array));
If false its a single dimension array if true its a multi dimension array.
current will give you the first element of your array and check if the first element is an array or not by is_array function.
You can also do a simple check like this:
$array = array('yo'=>'dream', 'mydear'=> array('anotherYo'=>'dream'));
$array1 = array('yo'=>'dream', 'mydear'=> 'not_array');
function is_multi_dimensional($array){
$flag = 0;
while(list($k,$value)=each($array)){
if(is_array($value))
$flag = 1;
}
return $flag;
}
echo is_multi_dimensional($array); // returns 1
echo is_multi_dimensional($array1); // returns 0
I think this one is classy (props to another user I don't know his username):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
In my case. I stuck in vary strange condition.
1st case = array("data"=> "name");
2nd case = array("data"=> array("name"=>"username","fname"=>"fname"));
But if data has array instead of value then sizeof() or count() function not work for this condition. Then i create custom function to check.
If first index of array have value then it return "only value"
But if index have array instead of value then it return "has array"
I use this way
function is_multi($a) {
foreach ($a as $v) {
if (is_array($v))
{
return "has array";
break;
}
break;
}
return 'only value';
}
Special thanks to Vinko Vrsalovic
Its as simple as
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
This function will return int number of array dimensions (stolen from here).
function countdim($array)
{
if (is_array(reset($array)))
$return = countdim(reset($array)) + 1;
else
$return = 1;
return $return;
}
Try as follows
if (count($arrayList) != count($arrayList, COUNT_RECURSIVE))
{
echo 'arrayList is multidimensional';
}else{
echo 'arrayList is no multidimensional';
}
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);
Here is a nice one liner. It iterates over every key to check if the value at that key is an array. This will ensure true

Categories