PHP if in_array for multiple values - php

I have an array that is generated with anywhere between 3 and 12 values, it generates the array from account information;
$result = $ad->user()->groups($user['username']);
I want to check this array for multiple values (around 4 or 5) and if any of them are in it do what's inside the if, I can do it for one value pretty easily via:
if (in_array("abc",$result)) { $this->login_session($user); }
Is there a simple way to check this one array for multiple values in it other than consecutive ORs:
if (in_array("abc",$result) || in_array("123",$result) || in_array("def",$result) || in_array("456",$result) ) {
$this->login_session($user);
}

Try and see if this is helpful:
if(array_intersect($result, array('abc', '123', 'def'))) {
$this->login_session($user);
}

This should be what you are after:
$a = array(1,2,3,4,5);
$b = array(6,8);
function is_in_array($needle, $haystack) {
foreach ($needle as $stack) {
if (in_array($stack, $haystack)) {
return true;
}
}
return false;
}
var_dump(is_in_array($b, $a));
Basically loops through needle and runs an in array of it on the haystack. returns true once something is found, else it returns false.

Related

PHP In_MultiArray Function

on http://php.net/manual/en/function.in-array.php - if you scroll down it gives a function to determine if a string is inside of a query in a multidimensional array. "If you found yourself in need of a multidimensional array in_array like function you can use the one below. Works in a fair amount of time"
Here's original code(working):
function in_multiarray($elem, $array)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom] == $elem)
return true;
else
if(is_array($array[$bottom]))
if(in_multiarray($elem, ($array[$bottom])))
return true;
$bottom++;
}
return false;
}
What I'm trying to do is instead of returning 'true' or 'false' - i'd like to return the ROW #. So my initial thought was to simply replace 'return true' with 'return $bottom; however it isn't returning the record number.
Modified Function (not working);
function in_multiarray($elem, $array)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom] == $elem)
return $bottom;
else
if(is_array($array[$bottom]))
if(in_multiarray($elem, ($array[$bottom])))
return $bottom;
$bottom++;
}
return false;
}
Does anyone have an idea how to modify this function to return the ROW number that contains the match?
Here's a sample of the array...
$sample = array
array ("oldpage1.php","newpage1.php"),
array ("oldpage2.php","newpage2.php"),
array ("oldpage3.php","newpage3.php"),
array ("oldpage4.php","newpage4.php"),
array ("oldpage5.php","newpage5.php")
etc.
);
$row = in_multiarray($input, $sample);
Therefore if we know the row # we can fetch the new page with a simple
$newpage=$sample[$row][1]
Thanks!
It's worth noting that a function like in_array is intended to tell you whether or not a value exists inside of an array. What you're looking for seems to be a lot closer to something like array_search, which is designed to actually provide you with the key that points to a given value in the array.
However, because you're using a multi-dimensional array what you're actually looking for is the key that points to the array that contains the value. Hence we can divide and conquer this problem with two simple steps.
Map
Filter
The first step is to map a function in_array to every element in the first array (which is just another array). This will tell us which elements of the primary array contain an array that contains the value we're searching for.
$result = array_map(function($arr) use($search) {
return in_array($search, $arr, true);
}, $arr, [$searchValue]);
The second step is to then return the keys to those arrays (i.e. filter the result).
$keys = array_keys(array_filter($result));
Now you have all the keys of any matching items. If you want to apply as just one custom filter that specifies exactly where in the subarray to look, you could also do it like this.
$search = "oldpage2.php";
$sample = [
["oldpage1.php","newpage1.php"],
["oldpage2.php","newpage2.php"],
["oldpage3.php","newpage3.php"],
["oldpage4.php","newpage4.php"],
["oldpage5.php","newpage5.php"],
];
$keys = array_keys(array_filter($sample, function($arr) use($search) {
return $arr[0] === $search;
}));
var_dump($keys);
And you get...
array(1) {
[0]=>
int(1)
}
So now you know that "oldpage2.php" is in row 1 in $sample[1][0] which means you can do this to get the results out of the array.
foreach($keys as $key) {
echo "{$sample[$key][0]} maps to {$sample[$key][1]}\n";
}
Giving you
oldpage2.php maps to newpage2.php
If you want to return only the first result you could do that as well with a function like this using similar approach.
function getFirstMatch($search, Array $arr) {
foreach($arr as $key => $value) {
if ($value[0] === $search) {
return $value[1];
}
}
}
echo getFirstMatch("oldpage4.php", $sample); // newpage4.php
The Better Alternative
Of course, the better approach is to actually use the oldpage names as the actual keys of the array rather than do this expensive search through the array, because array lookup by key in PHP is just an O(1) operation, whereas this needle/haystack approach is O(N).
So we turn your $samples array into something like this and the search no longer requires any functions...
$samples = [
"oldpage1.php" => "newpage1.php",
"oldpage2.php" => "newpage2.php",
"oldpage3.php" => "newpage3.php",
"oldpage4.php" => "newpage4.php",
"oldpage5.php" => "newpage5.php",
];
Now you can just do something like $newpage = $samples[$search] and you get exactly what you're looking for. So echo $samples["oldpage2.php"] gives you "newpage2.php" directly without the intermediary step of searching through each array.
You can use the following code to get the full path to the value:
function in_multiarray($elem, $array, &$result)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom] == $elem) {
array_unshift($result, $bottom);
return true;
}
else {
if(is_array($array[$bottom])) {
if(in_multiarray($elem, $array[$bottom], $result)) {
array_unshift($result, $bottom);
return true;
}
}
}
$bottom++;
}
array_shift($result);
return false;
}
$sample = array(
array ("oldpage1.php","newpage1.php"),
array ("oldpage2.php","newpage2.php"),
array ("oldpage3.php","newpage3.php"),
array ("oldpage4.php","newpage4.php"),
array ("oldpage5.php","newpage5.php")
);
$input = "newpage5.php";
$result = [];
in_multiarray($input, $sample, $result);
print_r($result);
Path is stored in $result;

logic AND function on array with arbitrary/variable N values

I am stuck with a huge problem. I have a dynamic array that may contain anything between 0 and N values (for simplicity of the question, assume they are all boolean e.g. 0 or 1). Of course, once an array is defined/read, the number of values is not unknown anymore. And, I can exclude two trivial cases easily at the start: 0 (empty) and single value array.
What is left is the case of 2+ values inside an array and a need to perform logical AND operation on all of them.
For example:
$array = array
(
$a,
$b,
$c,
.
.
.
$n
);
$logical_function = $a && $b && $c && ... && $n;
Is this even possible to do somehow in PHP? I know how to generate dynamic / variable variables names from an array, but how do I write the AND part function?
Thanks
Here:
function logicalAnd(array $arr)
{
$result = true;
foreach($arr as $element)
{
$result = $result && $element;
if (!$result) { return false; }
}
return $result
}
If just one of the array element is false, the result will be false. So you can skip inspecting other elements when facing one false:
$result = true;
foreach($array as $arr)
{
if($arr)
$result = true;
else
{
$result = false;
break;
}
}
return $result;

How do I use PHP to compare one variable to any odd number instance of another variable?

I want to compare the session[name] to all the even instances of text.
For example:
$_SESSION['name'] === $text[1] or $text[2] or $text[4] or $text[6]
The problem with doing it like the way above is that the code above will limit to only 6. Is there any way to just say "compare this to all the even instances of '$text' "?
Basically what I'm trying to do is say:
Compare $_SESSION['name'] to all even info from the $Text array.
So for example if this was my array:
$text = array("info0", "info1", "info2", "info3")
I would want to compare something to all the even info instances in the array(ie: info0, info2)
The code:
//compare the strings
if ($_SESSION['name'] === $text[0] && $_SESSION['pass'] == $text[1]) {
//echo "That is the correct log-in information";
header("Location: home.php");
} else {
echo "That is not the correct log-in information.";
}
XaxD's answer is good, and probably what you are interested in, but if you are using an associative array and want to look at every other element of the array this will work:
function checkEvenValues($text)
{
$skip = array(true, false);
// set $iskp to 0 if you want the first element to be counted as even; else, set it to 1
$iskp = 0;
foreach ($text as $idx=>$val)
{
$skp = 1 - $skp;
if ($skip[$iskp]) continue;
if($_SESSION['name'] == $text[$i]) return (true);
}
return (false);
}
function checkEvenValues($text)
{
if($_SESSION['name'] === $text[1]) return true;
for($i = 2; $i < count($text); $i += 2)
{
if($_SESSION['name'] === $text[$i])
return true;
}
}
Presuming that your keys are the same as the numbers in your values ([0] => 'info0') etc, you can use something like this combining some PHP array functions to filter down to only even keys (including 1), then a strict in_array() check to determine if it's there:
function compareEvens($text, $compare) {
// swap keys for values (back again)
$evens = array_flip(
// apply custom filter function
array_filter(
// swap keys for values
array_flip($text),
// return if its even OR its one
function($key) {
return $key % 2 === 0 || $key === 1;
}
)
);
return in_array($compare, $evens, true);
}
Example:
$text = array("info0", "info1", "info2", "info3");
var_dump(compareEvens($text, 'info2')); // true
var_dump(compareEvens($text, 'info3')); // false
Docs:
array_flip()
array_filter()
in_array()

Is there a method to check if all array items are '0'?

I have an array
$data = array( 'a'=>'0', 'b'=>'0', 'c'=>'0', 'd'=>'0' );
I want to check if all array values are zero.
if( all array values are '0' ) {
echo "Got it";
} else {
echo "No";
}
Thanks
I suppose you could use array_filter() to get an array of all items that are non-zero ; and use empty() on that resulting array, to determine if it's empty or not.
For example, with your example array :
$data = array(
'a'=>'0',
'b'=>'0',
'c'=>'0',
'd'=>'0' );
Using the following portion of code :
$tmp = array_filter($data);
var_dump($tmp);
Would show you an empty array, containing no non-zero element :
array(0) {
}
And using something like this :
if (empty($tmp)) {
echo "All zeros!";
}
Would get you the following output :
All zeros!
On the other hand, with the following array :
$data = array(
'a'=>'0',
'b'=>'1',
'c'=>'0',
'd'=>'0' );
The $tmp array would contain :
array(1) {
["b"]=>
string(1) "1"
}
And, as such, would not be empty.
Note that not passing a callback as second parameter to array_filter() will work because (quoting) :
If no callback is supplied, all entries of input equal to FALSE (see
converting to boolean) will be removed.
How about:
// ditch the last argument to array_keys if you don't need strict equality
$allZeroes = count( $data ) == count( array_keys( $data, '0', true ) );
Use this:
$all_zero = true;
foreach($data as $value)
if($value != '0')
{
$all_zero = false;
break;
}
if($all_zero)
echo "Got it";
else
echo "No";
This is much faster (run time) than using array_filter as suggested in other answer.
you can loop the array and exit on the first non-zero value (loops until non-zero, so pretty fast, when a non-zero value is at the beginning of the array):
function allZeroes($arr) {
foreach($arr as $v) { if($v != 0) return false; }
return true;
}
or, use array_sum (loops complete array once):
function allZeroes($arr) {
return array_sum($arr) == 0;
}
#fireeyedboy had a very good point about summing: if negative values are involved, the result may very well be zero, even though the array consists of non-zero values
Another way:
if(array_fill(0,count($data),'0') === array_values($data)){
echo "All zeros";
}
Another quick solution might be:
if (intval(emplode('',$array))) {
// at least one non zero array item found
} else {
// all zeros
}
if (!array_filter($data)) {
// empty (all values are 0, NULL or FALSE)
}
else {
// not empty
}
I'm a bit late to the party, but how about this:
$testdata = array_flip($data);
if(count($testdata) == 1 and !empty($testdata[0])){
// must be all zeros
}
A similar trick uses array_unique().
You can use this function
function all_zeros($array){//true if all elements are zeros
$flag = true;
foreach($array as $a){
if($a != 0)
$flag = false;
}
return $flag;
}
You can use this one-liner: (Demo)
var_export(!(int)implode($array));
$array = [0, 0, 0, 0]; returns true
$array = [0, 0, 1, 0]; returns false
This is likely to perform very well because there is only one function call.
My solution uses no glue when imploding, then explicitly casts the generated string as an integer, then uses negation to evaluate 0 as true and non-zero as false. (Ordinarily, 0 evaluates as false and all other values evaluate to true.)
...but if I was doing this for work, I'd probably just use !array_filter($array)

using array_map to test values?

Is it possible to use array_map() to test values of an array? I want to make sure that all elements of an array are numeric.
I've tried both
$arrays = array(
array(0,1,2,3 )
, array ( 0,1, "a", 5 )
);
foreach ( $arrays as $arr ) {
if ( array_map("is_numeric", $arr) === FALSE ) {
echo "FALSE\n";
} else {
echo "TRUE\n";
}
}
and
$arrays = array(
array(0,1,2,3 )
, array ( 0,1, "a", 5 )
);
foreach ( $arrays as $arr ) {
if ( ( array_map("is_numeric", $arr) ) === FALSE ) {
echo "FALSE\n";
} else {
echo "TRUE\n";
}
}
And for both I get
TRUE
TRUE
Can this be done? If so, what am I doing wrong?
Note: I am aware that I can get my desired functionality from a foreach loop.
array_map returns an array. So it will always be considered 'true'. Now, if you array_search for FALSE, you might be able to get the desire effects.
From the PHP.net Page
array_map() returns an array containing all the elements of
arr1 after applying the callback function to each one.
This means that currently you have an array that contains true or false for each element. You would need to use array_search(false,$array) to find out if there are any false values.
I'm usually a big advocate of array_map(), array_filter(), etc., but in this case foreach() is going to be the best choice. The reason is that with array_map() and others it will go through the entire array no matter what. But for your purposes you only need to go through the array until you run into a value for which is_numeric() returns false, and as far as I know there's no way in PHP to break out of those methods.
In other words, if you have 1,000 items in your array and the 5th one isn't numeric, using array_map() will still check the remaining 995 values even though you already know the array doesn't pass your test. But if you use a foreach() instead and have it break on is_numeric() == false, then you'll only need to check those first five elements.
You could use filter, but it ends up with a horrible bit of code
$isAllNumeric = count(array_filter($arr, "is_numeric")) === count($arr)
Using a custom function makes it a bit better, but still not perfect
$isAllNumeric = count(array_filter($arr, function($x){return !is_numeric($x);})) === 0
But if you were using custom functions array_reduce would work, but it still has some failings.
$isAllNumeric = array_reduce($arr,
function($x, $y){ return $x && is_numeric($y); },
true);
The failings are that it won't break when it has found what it wants, so the functional suggestions above are not very efficient. You would need to write a function like this:
function array_find(array $array, $callback){
foreach ($array as $x){ //using iteration as PHP fails at recursion
if ( call_user_func($callback, array($x)) ){
return $x;
}
}
return false;
}
And use it like so
$isAllNumeric = array_find($arr, function($x){return !is_numeric($x);})) !== false;
i have two tiny but extremely useful functions in my "standard library"
function any($ary, $func) {
foreach($ary as $val)
if(call_user_func($func, $val)) return true;
return false;
}
function all($ary, $func) {
foreach($ary as $val)
if(!call_user_func($func, $val)) return false;
return true;
}
in your example
foreach ( $arrays as $arr )
echo all($arr, 'is_numeric') ? "ok" : "not ok";
A more elegant approach IMHO:
foreach ($arrays as $array)
{
if (array_product(array_map('is_numeric', $array)) == true)
{
echo "TRUE\n";
}
else
{
echo "FALSE\n";
}
}
This will return true if all the values are numeric and false if any of the values is not numeric.

Categories