Have
$my_arr_1 = array ("denied","denied","denied");
$my_arr_2 = array ("denied","denied","allowed");
Need a func that would check if all elements in the array equal to something:
in_array_all("denied",$my_arr_1); // => true
in_array_all("denied",$my_arr_2); // => false
Is there a php native function like in_array_all?
If not, what would be the most elegant way to write such a func?
function in_array_all($value, $array)
{
return (reset($array) == $value && count(array_unique($array)) == 1);
}
function in_array_all($needle,$haystack){
if(empty($needle) || empty($haystack)){
return false;
}
foreach($haystack as $k=>$v){
if($v != $needle){
return false;
}
}
return true;
}
And if you wanted to get really crazy:
function in_array_all($needle,$haystack){
if(empty($needle)){
throw new InvalidArgumentException("$needle must be a non-empty string. ".gettype($needle)." given.");
}
if(empty($haystack) || !is_array($haystack)){
throw new InvalidArgumentException("$haystack must be a non-empty array. ".gettype($haystack)." given.");
}
foreach($haystack as $k=>$v){
if($v != $needle){
return false;
}
}
return true;
}
I don't know the context of your code. But what about reversing the logic? Then you are able to use PHP's native function in_array.
$my_arr_1 = array ("denied","denied","denied");
$my_arr_2 = array ("denied","denied","allowed");
!in_array("allowed", $my_arr_1); // => true
!in_array("allowed", $my_arr_2); // => false
This entirely depends on your data set of course. But given the sample data, this would work. (Also, notice the negation ! in front of each method call to produce the desired boolean result).
Another solution using array_count_values():
function in_array_all(array $haystack, $needle) {
$count_map = array_count_values($haystack);
// in your case: [ 'denied' => 2, 'allowed' => 1 ]
return isset($count_map[$needle]) && $count_map[$needle] == count($haystack);
}
Richard's solution is best but does not have one closing paren ;-) - here is fixed and abridged:
function in_array_all($needle,$haystack)
{
if( empty($needle) || empty($haystack) ) return false;
foreach($haystack as $v)
{
if($v != $needle) return false;
}
return true;
}
Related
I want to check all elements of an array and find out, whether at least one of them is prefixed by a given string:
public function validateStringByPrefix(string $string, $prefix)
{
$valid = false;
if (is_string($prefix)) {
if (strpos($string, $prefix) === 0) {
$valid = true;
}
} elseif (is_array($prefix)) {
foreach ($prefix as $partPrefix) {
if (strpos($string, $partPrefix) === 0) {
$valid = true;
break;
}
}
}
return $valid;
}
Is it possible / How to to achieve the same a more efficient way?
(It's a cheap method, but it's called a lot of times in my application, so even a minimal improvement might appreciably increase the application's performance.)
You can try next solution:
public function validateStringByPrefix(string $string, $prefix)
{
return (bool)array_filter((array)$prefix, function($prefix) use ($string) {
return strpos($string, $prefix)===0;
});
}
P.S. In case you have few large arrays (with prefixes), my solution is less efficient and you can combine our approaches like this:
public function validateStringByPrefix(string $string, $prefix)
{
if($string=='') {
return false;
}
foreach ((array)$prefix AS $subprefix) {
if (strpos($string, $subprefix)===0) {
return true;
}
}
return false;
}
There are many ways to rome....
//your array to test for
$array=[];
//set valid to false
$valid=false;
//setup prefixes array or not
$prefix='whatever';
//make array if you dont have one
!is_array($prefix) AND $prefix=array($prefix);
//prepare for use as REGEX
$prefix=implode('|',$prefix);
//do the work
array_walk($array,function($val,$key) use(&$valid,$prefix){
if (!$valid && preg_match("#^($prefix)#",$key)) {
$valid = true;
}
});
var_export($valid);
I used preg_match here, because $prefix can be an array, so the math would be: n+ strpos() calls vs. one preg_match() call
And after a single item matches, no more preg_match are called, just iteration to the end and out.
How can I use foreach to return true or false.
For example, this isn't working.
function checkArray($myArray) {
foreach( $myArray as $key=>$value ) {
if(!$value == $condition) {
return false;
}
else {
return true;
}
}
if ($checkArray == true) {
// do something
}
What is the correct syntax for using foreach as true/false function? If you can't do it, could you use it to change an existing variable to true/false instead?
You would return true if the element was found/condition is true. And after the loop return false - if it had been found, this statement wouldn't have been reached.
function checkArray($myArray) {
foreach($myArray as $key => $value) {
if ($value == $condition) {
return true;
}
}
return false;
}
if (checkArray($array) === true) {
// ...
}
Of course true and false are interchangeable, depending on what output you expect.
If you're just trying to find a value you can use
if (in_array($lookup, $arrayToSearch)) { }
It'll be more efficient than enumerating the whole array.
I have an array of values and I'd like to check that all values are either string or numeric. What is the most efficient way to do this?
Currently I'm just checking for strings so I was just doing if (array_filter($arr, 'is_string') === $arr) which seems to be working.
See: PHP's is_string() and is_numeric() functions.
Combined with array_filter, you can then compare the two arrays to see if they are equal.
function isStringOrNumeric($in) {
// Return true if $in is either a string or numeric
return is_string($in) || is_numeric($in);
}
class Test{}
$a = array( 'one', 2, 'three', new Test());
$b = array_filter($a, 'isStringOrNumeric');
if($b === $a)
echo('Success!');
else
echo('Fail!');
More effective would be this:
function isStringNumberArray( $array){
foreach( $array as $val){
if( !is_string( $val) && !is_numeric( $val)){
return false;
}
}
return true;
}
This method:
won't create new array
will stop after first invalid value
If you're looking to do a single run through the array, you could write your own function to check each of the values against your specific criteria. Something like:
function is_string_or_numeric($var)
{
return is_string($var) || is_numeric($var);
}
Then you can filter your array like:
if (array_filter($arr, 'is_string_or_numeric') === $arr)
PHP's ctype functions, specifically ctype_alpha() and ctype_digit() are also worth looking at:
http://php.net/manual/en/book.ctype.php
Well, it really depends on what you mean by "either string or numeric" (this could mean is_numeric(X), or is_int(X) || is_string(X), or any number of other things). Probably the most efficient way (though it's more verbose) is this:
public function isValid(array $array) {
$valid = TRUE;
foreach ($arr as $value) {
if (!is_int($value) && !is_string($value)) {
$valid = FALSE;
break;
}
}
return $valid;
}
Lots of answers for this one. If you want to use the method you've been using, you will want to write your own function for this.
so for each element in the array you are going to check if it is a number:
function isNumber($array_element) {
return is_numeric($array_element);
}
and then call that test function using array_filter
if (array_filter($arr, 'is_number') {
// is a number code here.
}
Have you written a function 'is_string()'? If not, array_filter($arr, 'is_string') may not be working the way you think it is.).
Two facts:
foreach is faster than array_map(), because it doesnt call a function on each iteration
using the === Operator is faster than is_int / is_string, like so:
if ((int)$value === $value) echo "its an int";
if ((string)$value === $value) echo "its a string";
How do you verify an array contains only values that are integers?
I'd like to be able to check an array and end up with a boolean value of true if the array contains only integers and false if there are any other characters in the array. I know I can loop through the array and check each element individually and return true or false depending on the presence of non-numeric data:
For example:
$only_integers = array(1,2,3,4,5,6,7,8,9,10);
$letters_and_numbers = array('a',1,'b',2,'c',3);
function arrayHasOnlyInts($array)
{
foreach ($array as $value)
{
if (!is_int($value)) // there are several ways to do this
{
return false;
}
}
return true;
}
$has_only_ints = arrayHasOnlyInts($only_integers ); // true
$has_only_ints = arrayHasOnlyInts($letters_and_numbers ); // false
But is there a more concise way to do this using native PHP functionality that I haven't thought of?
Note: For my current task I will only need to verify one dimensional arrays. But if there is a solution that works recursively I'd be appreciative to see that to.
$only_integers === array_filter($only_integers, 'is_int'); // true
$letters_and_numbers === array_filter($letters_and_numbers, 'is_int'); // false
It helps to define two helper, higher-order functions:
/**
* Tell whether all members of $elems validate the $predicate.
*
* all(array(), 'is_int') -> true
* all(array(1, 2, 3), 'is_int'); -> true
* all(array(1, 2, 'a'), 'is_int'); -> false
*/
function all($elems, $predicate) {
foreach ($elems as $elem) {
if (!call_user_func($predicate, $elem)) {
return false;
}
}
return true;
}
/**
* Tell whether any member of $elems validates the $predicate.
*
* any(array(), 'is_int') -> false
* any(array('a', 'b', 'c'), 'is_int'); -> false
* any(array(1, 'a', 'b'), 'is_int'); -> true
*/
function any($elems, $predicate) {
foreach ($elems as $elem) {
if (call_user_func($predicate, $elem)) {
return true;
}
}
return false;
}
<?php
$only_integers = array(1,2,3,4,5,6,7,8,9,10);
$letters_and_numbers = array('a',1,'b',2,'c',3);
function arrayHasOnlyInts($array){
$test = implode('',$array);
return is_numeric($test);
}
echo "numbers:". $has_only_ints = arrayHasOnlyInts($only_integers )."<br />"; // true
echo "letters:". $has_only_ints = arrayHasOnlyInts($letters_and_numbers )."<br />"; // false
echo 'goodbye';
?>
Another alternative, though probably slower than other solutions posted here:
function arrayHasOnlyInts($arr) {
$nonints = preg_grep('/\D/', $arr); // returns array of elements with non-ints
return(count($nonints) == 0); // if array has 0 elements, there's no non-ints
}
There's always array_reduce():
array_reduce($array, function($a, $b) { return $a && is_int($b); }, true);
But I would favor the fastest solution (which is what you supplied) over the most concise.
function arrayHasOnlyInts($array) {
return array_reduce(
$array,
function($result,$element) {
return is_null($result) || $result && is_int($element);
}
);
}
returns true if array has only integers, false if at least one element is not an integer, and null if array is empty.
Why don't we give a go to Exceptions?
Take any built in array function that accepts a user callback (array_filter(), array_walk(), even sorting functions like usort() etc.) and throw an Exception in the callback. E.g. for multidimensional arrays:
function arrayHasOnlyInts($array)
{
if ( ! count($array)) {
return false;
}
try {
array_walk_recursive($array, function ($value) {
if ( ! is_int($value)) {
throw new InvalidArgumentException('Not int');
}
return true;
});
} catch (InvalidArgumentException $e) {
return false;
}
return true;
}
It's certainly not the most concise, but a versatile way.
I have an array within an array.
$a = array ( 0 => array ( 'value' => 'America', ), 1 => array ( 'value' => 'England', ), )
How do I check if 'America' exists in the array? The America array could be any key, and there could be any number of subarrays, so a generalized solution please.
Looking on the php manual I see in_array, but that only works for the top layer. so something like in_array("America", $a) would not work.
Thanks.
A general solution would be:
function deep_in_array($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && deep_in_array($needle, $element))
return true;
}
return false;
}
The reason why I chose to use in_array and a loop is: Before I examine deeper levels of the array structure, I make sure, that the searched value is not in the current level. This way, I hope the code to be faster than doing some kind of depth-first search method.
Of course if your array is always 2 dimensional and you only want to search in this kind of arrays, then this is faster:
function in_2d_array($needle, $haystack) {
foreach($haystack as $element) {
if(in_array($needle, $element))
return true;
}
return false;
}
PHP doesn't have a native array_search_recursive() function, but you can define one:
function array_search_recursive($needle, $haystack) {
foreach ($haystack as $value) {
if (is_array($value) && array_search_recursive($needle, $value)) return true;
else if ($value == $needle) return true;
}
return false;
}
Untested but you get the idea.
in_array("America", array_column($a, 'value'))
function search($a,$searchval){ //$a - array; $searchval - search value;
if(is_array($a)) {
foreach($a as $val){
if(is_array($val))
if(in_array($searchval,$val)) return true;
}
}
else return false;
}
search($a, 'America'); //function call