min function that ignores negative values in php - php

I have three numbers:
$a = 1
$b = 5
$c = 8
I want to find the minimum and I used the PHP min function for that. In this case it will give 1.
But if there is a negative number, like
$a = - 4
$b = 3
$c = 9
now the PHP min() should give $b and not $a, as I just want to compare positive values, which are $b and $c. I want to ignore the negative number.
Is there any way in PHP? I thought I will check if the value is negative or positive and then use min, but I couldn't think of a way how I can pass only the positive values to min().
Or should I just see if it's negative and then make it 0, then do something else?

You should simply filter our the negative values first.
This is done easily if you have all of them in an array, e.g.
$a = - 4;
$b = 3;
$c = 9;
$values = array($a, $b, $c);
$values = array_filter($values, function($v) { return $v >= 0; });
$min = min($values);
print_r($min);
The above example uses an anonymous function so it only works in PHP >= 5.3, but you can do the same in earlier versions with
$values = array_filter($values, create_function('$v', 'return $v >= 0;'));
See it in action.

$INF=0x7FFFFFFF;
min($a>0?$a:$INF,$b>0?$b:$INF,$c>0?$c:$INF)
or
min(array_filter(array($a,$b,$c),function($x){
return $x>0;
}));

http://codepad.org/DVgMs7JF
<?
$test = array(-1, 2, 3);
function removeNegative($var)
{
if ($var > 0)
return $var;
}
$test2 = array_filter($test, "removeNegative");
var_dump(min($test2));
?>

Related

php - Convert array values to same values with pipe separated (NOT STRING) [duplicate]

If I have an array of flags and I want to combine them with a bitwise conjunction
ie:
$foo = array(flag1, flag2);
into
$bar = flag1 | flag2;
Does PHP have any good functions that will do this nicely for me already?
The array_reduce will reduce an array to a single value for you:
$res = array_reduce($array, function($a, $b) { return $a | $b; }, 0);
Reduce is also sometimes called fold (fold left or fold right) in other languages.
You could do it like so
$bar = $foo[0] | $foo[1]
If the size of your array is unknown you could use array_reduce like this
// in php > 5.3
$values = array_reduce($flagArray, function($a, $b) { return $a | $b; });
// in php <= 5.2
$values = array_reduce($flagArray, create_function('$a, $b', 'return $a | $b'));
$values = array_reduce($foo,function($a,$b){return is_null($a) ? $b : $a | $b;});
PHP < 5.3 (no closures), either of these two:
function _mybitor($a,$b){return is_null($a) ? $b : $a | $b;}
$values = array_reduce($foo,'_mybitor');
or
$values = array_reduce($foo,create_function('$a,$b','return is_null($a) ? $b : $a | $b;'));
);
A simple suggestion to the accepted answer: create a sibling to array_sum.
function array_or (array $array): int {
return array_reduce($array, function($a, $b) { return $a | $b; }, 0);
}

If a string is not matching one of 3 option in PHP

This is the code I used to have to check if $A doesn't match $B
if($A!=$B) {
$set = array();
echo $val= str_replace('\\/', '/', json_encode($set));
//echo print_r($_SERVER);
exit;
}
Now I need the opposite of this condition: ($A need to match one of these $B,$C or $D)
A simple shortcut to seeing if a value matches one of multiple values you can put the values to be compared against ($B, $C, and $D) into an array and then use in_array() to see if the original value ($A) matches any of them.
if (in_array($A, [$B, $C, $D])) {
// ...
}
If you don't want it to match any of $B, $C, or $D just use !:
if (!in_array($A, [$B, $C, $D])) {
// ...
}
You can use array_search
$B = 'B';
$C = 'C';
$D = 'D';
//match B
$A = 'B';
$options = [$B, $C, $D];
if (false !== ($index = array_search($A, $options ))) {
echo "Match: {$index} '{$options[$index]}'";
}
Output
Match: 0 'B'
Sandbox
The nice thing here is you can set the $index and use that to tell which one matched later.
Note you have to use false !== because array search returns the index where the match happened at, so it can happen on the first array element which is index 0. As we know PHP can treat 0 as false (in this case the condition would fail when it should pass). However, when we use the strict type check PHP also compares the type and INT 0 is not BOOL false (which passes the condition).
for reference.
http://php.net/manual/en/function.array-search.php
Another probably the most efficient way is to use isset, and use keys instead of values:
$options = [$B=>1,$C=>1,$D=>1]; //values don't matter
if(!isset($options[$A])){
//....
}

Evaluate concatonated operator with numbers

I'm struggling with a small piece of code that doesn't want to evaluate itself :
$t = 5;
$s = "<=";
$r = 6;
var_dump($t.$s.$r);
Here the var_dump return "5<=6" which make sense but I just want it to tell me if 5 is inferior or equal to 6 with a boolean.
I wanted to know if there was an other way to get this boolean beside using an eval() or a switch throught all the possible operator
Thanks in advance.
If you want a safe and flexible solution, this allows you to define a method which is executed depending on the operator matching the key in an array, it only works with two operands, but the last one in the examples # just multiplies the first value by 4 and returns the value...
$operators = [ "<=" => function ($a, $b) { return $a <= $b;},
"<" => function ($a, $b) { return $a < $b;},
">=" => function ($a, $b) { return $a >= $b;},
">" => function ($a, $b) { return $a > $b;},
"#" => function ($a) { return $a * 4; }];
$t = 5;
$s = "<=";
$r = 6;
var_dump($operators[$s]($t,$r));
$s = "<";
var_dump($operators[$s]($t,$r));
$s = ">=";
var_dump($operators[$s]($t,$r));
$s = ">";
var_dump($operators[$s]($t,$r));
$s = "#";
var_dump($operators[$s]($t,$r));
gives...
/home/nigel/workspace2/Test/t1.php:14:
bool(true)
/home/nigel/workspace2/Test/t1.php:17:
bool(true)
/home/nigel/workspace2/Test/t1.php:20:
bool(false)
/home/nigel/workspace2/Test/t1.php:23:
bool(false)
/home/nigel/workspace2/Test/t1.php:26:
int(20)
It's a bit convoluted, but also extensible and safe.
while it is generally not a good idea to have code usch as this (evaluating code that is sstored as plaintext), there is a function for exactly this: eval().
eval() does what you expect PHP to do naturally: evaluate valid code stored in a string.
eval("var_dump(".$t.$s.$r.");"); will do the job - however, since any code inside those variables is executed without question, it can be a security risk, or at least introduce some hard-to-debug errors.
(the extra quoting and the ; are needed to make the code inside eval actually valid PHP code)

Is it possible to show operations being done in php?

For example, suppose i have this very simple function
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
This normally would output 3 directly. But is it possible to make php show the operations being done, like 3 = 1 + 2? (similar to a console.log) Thanks!
You can customize the function a little bit to achieve this:
function Sum($a, $b)
{
$c = $a + $b;
return "{$c} = {$a} + {$b}";
}
$a = 1;
$b = 2;
echo sum($a, $b);
Note that I've changed the function to use parameters. Using globals is not a very good idea. See this answer to know why.
The above code outputs:
3 = 1 + 2
If you want your function to perform multiple operations, you can create a switch block and define the operations, and display the corresponding symbol (+, -, x, รท etc.)

PHP short sentence of stating new vairable

I wonder if there is any way can short sentence to state a variable.
Purpose: only for if you are in a situation have to state 20 variables at the time. more convenience
$a = 1; $b = 2;
//Imagination like below
$a, $b = 1, 2;
$a = 1, $b = 2;
Thank you very much for your advice of alternatives.
(If you do not have any ideas, please do not accuse the way of why have to think about this), because arrray, (object) are alternatives, but not match what I need on my question
The closest you can get to that syntax is using list():
<?php
list ($a, $b) = array(1, 2);
echo $a . ' ' . $b; // prints "1 2"
Its magic!
EDIT:
For even more magic, you can use short array notation from PHP 5.4 onwards:
<?php
list($a, $b) = [1, 2];
print $a . ', ' . $b; // prints 1, 2
How is $a = 1, $b = 2; shorter than $a = 1; $b = 2; ?
If for any reason you need two assignments in one statement, you could to it with list:
list($a,$b) = array(1,2);
However, shortening is not a valid reason for this.

Categories