I have an if statement that is used in two different functions against the same conditions. The problem is that the conditions end up fairly long (5-7 ORs) and may need to be modified in the future. If they end up being modified, the conditions will change the same way in both functions.
Example of one if statement:
if ($this->object === 'one' || $this->object === 'two' || $this->object === 'three' ) {
echo 'Yes!';
} else {
echo 'No!';
};
I am thinking of creating an array and a function that will feed into the if statement but can't think of any way to get the if statement to check the condition rather than checking the presence of input.
$this->object = 'one';
$test_array = array('one', 'two', 'three');
function stmbuilder($array) {
$count = count($array);
$stm = '';
for ($i = 0; $i < $count; $i++) {
$intro = '$this->object ===';
$connector = ($i < $count-1 ? ' || ' : '');
$stm .= $intro . $array[$i] . $connector;
}
return $stm;
}
$condition = stmbuilder($test_array);
if ($condition) {
echo 'Yes!';
} else {
echo 'No!';
} //Will always echo Yes! since $condition has a value but does not check against what $this->object is
Any help is appreciated!
Why not just in_array()?
$arr = array('one', 'two', 'three');
in_array('four', $arr) -> false
in_array('two', $arr) -> true
Related
is there any way to check whether array_filter deleted any value from an array?
The solutions I've thought of are these ones:
$sample_array = ["values"];
$array_copy = $sample_array;
if (array_filter($sample_array, 'fn') === $array_copy) {
#Some value was deleted from the array
} else {
#The array was not modified
}
This one doesn't seem very efficient, as it has to copy the entire array.
$sample_array = ["values"];
$array_count = count($sample_array);
if (count(array_filter($sample_array, 'fn')) === $array_count) {
#The array was not modified
} else {
#Some value was deleted from the array
}
This one seems more efficient, though I was wondering if there was a more elegant way of approaching the issue.
Thank you beforehand.
You can extend your function to keep track of the change itself.
$array = [1, 2, 3, 4];
$changed = 0;
$new = array_filter($array, function($e) use (&$changed) {
$result = $e <= 2;
if(!$result) $changed++;
return $result;
});
Returns $changed as 2.
Use array_diff to compare two arrays.
if(array_diff($array_copy, $sample_array))
echo "not same";
Using 'count()' is IMHO the most elegant solution and, I suspect, may be a lot more efficient - you'd need to measure it. OTOH, for your consideration...
function fn($arg, $mode='default')
{
static $matched;
if ('default'==$mode) {
$result=real_filter_fn($arg);
$matched+=$result ? 1 : 0;
return $result;
}
$result=$matched;
$matched=0;
return $result;
}
If you want to keep track of the removed elements, you could do something like this.
$sample_array = ['values', 'test'];
$removed = []; // Contains all the removed values.
$new_array = array_filter($sample_array, function($value) use (&$removed) {
if($value == 'test') {
$removed[] = $value; // Adds the value to the removed array.
return false;
}
return true;
});
print_r($removed);
You could use a closure to change the state of a boolean variable:
$sample_array = [1,2,3,4];
$array_changed = false;
//Use closure to change $array_changed
print_r(array_filter($sample_array, function($var) use (&$array_changed) {
$check = (!($var & 1));
$array_changed = $array_changed?:$check;
return $check;
}));
if ($array_changed) {
#Some value was deleted from the array
} else {
#The array was not modified
}
[EDIT]
This is a simple speedtest of your solutions compared to mine:
/**********************SPEEDTEST**************************/
function fn ($var) {
return (!($var & 1));
}
$sample_array = [1,2,3,4];
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_changed = false;
//Use closure to change $array_changed
array_filter($sample_array, function($var) use (&$array_changed) {
$check = (!($var & 1));
$array_changed = $array_changed?:$check;
return $check;
});
if ($array_changed) {
#Some value was deleted from the array
} else {
#The array was not modified
}
}
$after = microtime(true);
echo "Using closure: " . ($after-$before)/$i . " sec/run\n";
echo '<br>';
/*******************************************************/
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_copy = $sample_array;
if (array_filter($sample_array, 'fn') === $array_copy) {
#Some value was deleted from the array
} else {
#The array was not modified
}
}
$after = microtime(true);
echo "Using array copy: " . ($after-$before)/$i . " sec/run\n";
echo '<br>';
/*******************************************************/
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
$array_count = count($sample_array);
if (count(array_filter($sample_array, 'fn')) === $array_count) {
#The array was not modified
} else {
#Some value was deleted from the array
}
}
$after = microtime(true);
echo "Using array count: " . ($after-$before)/$i . " sec/run\n";
The results:
Using closure: 9.1402053833008E-7 sec/run
Using array copy: 4.9885988235474E-7 sec/run
Using array count: 5.5881977081299E-7 sec/run
Maybe that helps with decision-making :)
I'm new to php and I try to make a simple program. to show a result for ex : if the array only contains a the $result will be "a" , if b the $result will be "b", if a & b then "ab" etc. in this case the array contains a, b, and c and for some reason when I run it only shows "c".
here's my code :
$a[0] = "b";
$a[1] = "a";
$a[2] = "c";
for ($j=0; $j<sizeof($a); $j++) {
for ($k=0; $k<sizeof($a); $k++) {
for ($l=0; $l<sizeof($a); $l++) {
if ($a[$j] == "a"){
$result="a";
}
elseif ($a[$j] == "b") {
$result="b";
}
elseif ($a[$j] == "c") {
$result="c";
}
elseif ($a[$j] == "a" and $a[$k] == "b") {
$result="ab";
}
elseif ($a[$j] == "c" and $a[$k] == "b" and $a[$l] == "a") {
$result="abc";
}
elseif ($a[$j] == "b" and $a[$k] == "c") {
$result="bc";
}
}
}
}
echo ($result);
thanks in advance
Use only one loop and three flags. Try something like this
$a[0] = "b";
$a[1] = "a";
$a[2] = "c";
$hasA = false;
$hasB = false;
$hasC = false;
for ($j=0; $j<sizeof($a); $j++) {
if ($a[$j] == "a"){
$hasA = true;
}
elseif ($a[$j] == "b"){
$hasB = true;
}
elseif ($a[$j] == "c"){
$hasC = true;
}
}
if ($hasA) echo 'a';
if ($hasB) echo 'b';
if ($hasC) echo 'c';
First of all those loops aren't really necessary.
Use php switches.
switch($value){
case "a":
// Actions here
case "b":
// Actions here
}
What you are doing in those for loops is keep overriding $result with a new value.
In the end it shows the last letter it found.
Aside from the fact, what purpose this code has. Try to look for a php debugger I would recommend using Xdebug.
A debugger helps a programmer detect problems by stepping into the code line by line and showing the state of every variable.
A good tutorial and development environnement tutorial is found here
Let's take a different approach:
$array="asdasd";
$check=$arry[0];
$all_the_same=true;
for($i=1; $i<count($array); $i++){
if(array[$i] !== $check){
$all_the_same=false;
break;
}
}
What I've done is to check all letters in the array to see if they're all the same, and set $all_the_same to false if they're not. To find out if the array has the letter you want:
if($check==="a")
echo "has 'a'";
or perhaps the more civilized switch / case statement.
The problem with your code is that you run three loops over the same data. $j changes very slowly (every sizeof($a) squared to be precise) and it's the first thing you check so it's no surprise it always shows "c".
$a[0] = "b";
$a[1] = "a";
$a[2] = "c";
$result = '';
foreach($a as $value) {
if($value == 'a')
$result .= 'a';
if($value == 'b')
$result .= 'b';
if($value == 'c')
$result .= 'c';
}
echo $result;
Here is a smoother version of what you tried to do!
sort($array);
implode( array_unique( $array ) );
As #GarethL had mentioned
here is a simpler way to achieve this:
$a = array('a', 'b', 'c');
$result = '';
if(in_array('a', $a)){
$result .= 'a';
}
if(in_array('b', $a)){
$result .= 'b';
}
if(in_array('c', $a)){
$result .= 'c';
}
echo $result;
For the intention of the question, may meet this simple code
<?php
$a[0] = "b";
$a[1] = "a";
$a[2] = "c";
$result = implode($a);
echo $result;
Let's say I want to check for simple mathematical progression. I understand I can do it like this:
if ($a<$b and $b<$c and $c<$d and $d<$e and $e<$f) { echo OK; }
Is there a way to do it in a more convenient way? Like so
if ($a..$f isprog(<)) { echo OK; }
I don 't know if I get your problem right. But propably the solution for your progression could be the SplHeap object of the SPL delivered with php.
$stack = new SplMaxHeap();
$stack->insert(1);
$stack->insert(3);
$stack->insert(2);
$stack->insert(4);
$stack->insert(5);
foreach ($stack as $value) {
echo $value . "\n";
}
// output will be: 5, 4, 3, 2, 1
I havent heard of something like this, but how about using simple function:
function checkProgress($vars){ //to make it easie i assume that vars can be given in an array
$result = true;
for ($i=0; $i<= count($vars); $i++){
if ($i>0 && $vars[$i] > $vars[$i-1]) continue;
$result = false;
}
return $result;
}
Solved it quick and dirty:
function ispositiveprogression($vars) {
$num=count($vars)-1;
while ($num) {
$result = true;
if ($vars[$num] > $vars[$num-1]) {
$num--;
}
else { $result = false; break; }
}
return $result;
}
Create an array of values, iterate over them and maintaining a flag that checks if the current element value is greater than / less than that of the next value. Unlike some of the solutions in this thread, this doesn't loop through the whole array. It stops looping when it discovers the first value that's not a progression. This will be a lot more faster if the operation involves a lot of numbers.
function checkIfProg($arr, $compare) {
$flag = true;
for ($i = 0, $c = count($arr); $i < $c; $i++) {
if ($compare == '<') {
if (isset($arr[$i + 1]) && $arr[$i] > $arr[$i + 1]) {
$flag = false;
break;
}
} elseif ($compare == '>') {
if (isset($arr[$i + 1]) && $arr[$i] < $arr[$i + 1]) {
$flag = false;
break;
}
}
}
return $flag;
}
Usage:
$a = 2;
$b = 3;
$c = 4;
$d = 5;
$e = 9;
$f = 22;
$arr = array($a, $b, $c, $d, $e, $f);
var_dump(checkIfProg($arr, '<')); // => bool(true)
If you want the array to be created dynamically, you could use some variable variable magic to achieve this:
$arr = array();
foreach (range('a','f') as $v) {
$arr[] = $$v;
}
This will create an array containing all the values of variables from $a ... $f.
Consider the following array.
$a['a'] = 1;
$a['b'] = 2;
$a['c'] = 3;
$a['d'] = 4;
and then i am looping the array
foreach( $a as $q => $x )
{
# Some operations ....
if( isLastElement == false ){
#Want to do some more operation
}
}
How can i know that the current position is last or not ?
Thanks.
Take a key of last element & compare.
$last_key = end(array_keys($a));
foreach( $a as $q => $x )
{
# Some operations ....
if( $q == $last_key){
#Your last element
}
}
foreach (array_slice($a, 0, -1) as $q => $x) {
}
extraProcessing(array_slice($a, -1));
EDIT:
I guess the first array_slice is not necessary if you want to do the same processing on the last element. Actually neither is the last.
foreach ($a as $q => $x) {
}
extraProcessing($q, $x);
The last elements are still available after the loop.
You can use the end() function for this operation.
<?php
$a['a'] = 1;
$a['b'] = 2;
$a['c'] = 3;
$a['d'] = 4;
$endkey= end(array_keys($a));
foreach( $a as $q => $x )
{
# Some operations ....
if( $endkey == $q ){
#Want to do some more operation
echo 'last key = '.$q.' and value ='.$x;
}
}
?>
How to check whether the PHP variable is an array?
$value is my PHP variable and how to check whether it is an array?
echo is_array($variable);
http://us3.php.net/is_array
php has function named is_array($var) which returns bool to indicate whether parameter is array or not
http://ir.php.net/is_array
is_array — Finds whether a variable is an array
http://uk.php.net/is_array
I'm adding a late answer here as I think I've got a better solution if people are using multiple array checks.
If you're simply checking a single array, then using PHP's is_array() does the job just fine.
if (is_array($users)) {
is an array
} else {
is not an array
}
However, if you're checking multiple arrays - in a loop for example - then there is a much better performing solution for this, using a cast:
if ( (array) $users !== $users ) {
// is not an array
} else {
// is an array
}
THE PROOF
If you run this performance test, you will see quite a performance difference:
<?php
$count = 1000000;
$test = array('im', 'an', 'array');
$test2 = 'im not an array';
$test3 = (object) array('im' => 'not', 'going' => 'to be', 'an' => 'array');
$test4 = 42;
// Set this now so the first for loop doesn't do the extra work.
$i = $start_time = $end_time = 0;
$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (!is_array($test) || is_array($test2) || is_array($test3) || is_array($test4)) {
echo 'error';
break;
}
}
$end_time = microtime(true);
echo 'is_array : '.($end_time - $start_time)."\n";
$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
if (!(array) $test === $test || (array) $test2 === $test2 || (array) $test3 === $test3 || (array) $test4 === $test4) {
echo 'error';
break;
}
}
$end_time = microtime(true);
echo 'cast, === : '.($end_time - $start_time)."\n";
echo "\nTested $count iterations."
?>
THE RESULT
is_array : 7.9920151233673
cast, === : 1.8978719711304