I have an associative array in which I need to count the number of boolean true values within.
The end result is to create an if statement in which would return true when only one true value exists within the array. It would need to return false if there are more then one true values within the array, or if there are no true values within the array.
I know the best route would be to use count and in_array in some form. I'm not sure this would work, just off the top of my head but even if it does, is this the best way?
$array(a->true,b->false,c->true)
if (count(in_array(true,$array,true)) == 1)
{
return true
}
else
{
return false
}
I would use array_filter.
$array = array(true, true, false, false);
echo count(array_filter($array));
//outputs: 2
Array_filter will remove values that are false-y (value == false). Then just get a count. If you need to filter based on some special value, like if you are looking for a specific value, array_filter accepts an optional second parameter that is a function you can define to return whether a value is true (not filtered) or false (filtered out).
Since TRUE is casted to 1 and FALSE is casted to 0. You can also use array_sum
$array = array('a'=>true,'b'=>false,'c'=>true);
if(array_sum($array) == 1) {
//one and only one true in the array
}
From the doc : "FALSE will yield 0 (zero), and TRUE will yield 1 (one)."
Try this approach :
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Result :
Array
(
[1] => 2
[hello] => 2
[world] => 1
)
Documentation
like this?
$trues = 0;
foreach((array)$array as $arr) {
$trues += ($arr ? 1 : 0);
}
return ($trues==1);
Have you tried using array_count_values to get an array with everything counted? Then check how many true's there are?
Related
I want to remove NULL, FALSE and '' values .
I used array_filter but it removes the 0' s also.
Is there any function to do what I want?
array(NULL,FALSE,'',0,1) -> array(0,1)
array_filter should work fine if you use the identical comparison operator.
here's an example
$values = [NULL, FALSE, '', 0, 1];
function myFilter($var){
return ($var !== NULL && $var !== FALSE && $var !== '');
}
$res = array_filter($values, 'myFilter');
Or if you don't want to define a filtering function, you can also use an anonymous function (closure):
$res = array_filter($values, function($value) {
return ($value !== null && $value !== false && $value !== '');
});
If you just need the numeric values you can use is_numeric as your callback: example
$res = array_filter($values, 'is_numeric');
From http://php.net/manual/en/function.array-filter.php#111091 :
If you want to remove NULL, FALSE and Empty Strings, but leave values of 0, you can use strlen as the callback function:
array_filter($array, 'strlen');
array_filter doesn't work because, by default, it removes anything that is equivalent to FALSE, and PHP considers 0 to be equivalent to false. The PHP manual has this to say on the subject:
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
You can pass a second parameter to array_filter with a callback to a function you write yourself, which tells array_filter whether or not to remove the item.
Assuming you want to remove all FALSE-equivalent values except zeroes, this is an easy function to write:
function RemoveFalseButNotZero($value) {
return ($value || is_numeric($value));
}
Then you just overwrite the original array with the filtered array:
$array = array_filter($array, "RemoveFalseButNotZero");
Use a custom callback function with array_filter. See this example, lifted from PHP manual, on how to use call back functions. The callback function in the example is filtering based on odd/even; you can write a little function to filter based on your requirements.
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
function even($var)
{
// returns whether the input integer is even
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
One-liners are always nice.
$clean_array = array_diff(array_map('trim', $my_array), array('', NULL, FALSE));
Explanation:
1st parameter of array_diff: The trimmed version of $my_array. Using array_map, surrounding whitespace is trimmed from every element via the trim function. It is good to use the trimmed version in case an element contains a string that is nothing but whitespace (i.e. tabs, spaces), which I assume would also want to be removed. You could just as easily use $my_array for the 1st parameter if you don't want to trim the elements.
2nd parameter of array_diff: An array of items that you would like to remove from $my_array.
Output: An array of elements that are contained in the 1st array that are not also contained in the 2nd array. In this case, because '', NULL, and FALSE are within the 2nd array, they can never be returned by array_diff.
EDIT:
It turns out you don't need to have NULL and FALSE in the 2nd array. Instead you can just have '', and it will work the same way:
$clean_array = array_diff(array_map('trim', $my_array), array(''));
function my_filter($var)
{
// returns values that are neither false nor null (but can be 0)
return ($var !== false && $var !== null && $var !== '');
}
$entry = array(
0 => 'foo',
1 => false,
2 => -1,
3 => null,
4 => '',
5 => 0
);
print_r(array_filter($entry, 'my_filter'));
Outputs:
Array
(
[0] => foo
[2] => -1
[5] => 0
)
check whether it is less than 1 and greater than -1 if then dont remove it...
$arrayValue = (NULL,FALSE,'',0,1);
$newArray = array();
foreach($arrayValue as $value) {
if(is_int($value) || ($value>-1 && $value <1)) {
$newArray[] = $value;
}
}
print_r($newArray);
Alternatively you can use array_filter with the 'strlen' parameter:
// removes all NULL, FALSE and Empty Strings but leaves 0 (zero) values
$result = array_filter($array, 'strlen');
https://www.php.net/manual/en/function.array-filter.php#111091
function ExtArray($linksArray){
foreach ($linksArray as $key => $link)
{
if ($linksArray[$key] == '' || $linksArray[$key] == NULL || $linksArray[$key] == FALSE || $linksArray[$key] == '')
{
unset($linksArray[$key]);
}else {
return $linksArray[$key];
}
}
}
This function may help you
I want to verify if a levenshtein of factor <= 2 is present in an array. So:
in_array("test", $some_array);
to something like "check if in array, can have errors if levenshtein factor <= 2, by comparison"
levenshtein("test", $element_of_array_by_'in_array'_function);
Is this possible or do I have to iterate the array?
This should work for you:
You are looking for array_reduce(). With this you can reduce your array to one single return value.
You start with FALSE as return value. Then you loop through each array element and check if the return value of levenshtein() is smaller or equals 2.
If not then your return value of array_reduce() won't change and is still FALSE. If it is smaller or equals 2 you change the value to TRUE and array_reduce() will return TRUE.
array_reduce($some_array, function($keep, $v){
if(levenshtein($v, "test") <= 2)
return $keep = TRUE;
return $keep;
}, FALSE);
EDIT2: This goes to the top for a reason. This question is asked wrong, but I won´t change the title, since maybe other people are caught in this misstake. I am NOT looking for an "average" - I merely want to exit with the first "false" in an array.
My though to this questions were quite twisted - therefore I asked the wrong question.
Anyway: As stated, I won´t change the question itself.
What I want to do is basically calculate something like a boolean average of an array. I know about booleans and that they are not meant to be something with an average, but please read on to see what I am doing.
My array looks like this:
$array = array(
true,
false,
true,
true
);
I now want to get an AND-operation done on this array to see, if everything in there is true or if a subfunction returned false. This is basically a list of results from different subfunctions.
This specific example then should return false, because $array[1] is false.
EDIT:
What I am looking for is a builtin PHP-function which seems not to exists. A custom implementation has the advantage to exit the iteration over this array in comparison to in_array() which might not do this.
Can you help me out, stackoverflow?
Try in_array:
$array = array(
true,
false,
true,
true
);
echo in_array(false, $array);
If one of the elements is false, it will return false otherwise it returns true.
Update: in_array, returns out of the loop as soon as the searched value is matched. The worst case I suppose is when you have a single false at the end of the searched array. The linked source are for PHP 5.3.
As far as strict checking is concerned, you can do so passing in the third parameter to in_array:
echo in_array(false, $array, true);
Come on, it would appear you didn't even try:
function checkArray(array $in)
{
foreach ($in as $bool)
{
if (!$bool)//replace with type&value checking if that's what you're after
return false;
}
return true;
}
var_dump(checkArray(array(true, false, true, true)));//false
var_dump(checkArray(array(true, true)));//true
There are, of course, a bunch of alternative ways to do what you want/need, depending on what the actual data will look like. If it's all booleans:
if (array_sum($array) != count($array))
{//true == 1, array_sum(array(true, true)) == count(array(true, true)) == 2
echo 'array contains false, or non-boolean values, like 123';
}
//for a real average:
$avg = round(array_sum($array)/count($array));
The latter will yield 1 if 50%>= of the values in the array are true, and 0 otherwise. It's then a simple matter of casting that value to a boolean to get the "average bool value":
$avg = (bool) round(
array_sum($array)/count($array)
);
or, for example:
$valsAsKey = array_flip(
array_map(
'intval',//make ints
$array
)
);
if (isset($valsAsKey[0]))
{//(int) false === 0
echo 'False in array';
}
Though these approaches don't use iteration explicitly, they do iterate the array data implicitly. A quick test did show that the simple foreach outperformed the other approaches here.
I have tried around a lot, until i came to this final result.
This is my code:
<?php
$array = array();
$array[] = true;
$array[] = false;
$array[] = false;
$array[] = true;
$array[] = false;
var_dump($array);
if((count($array)/2) <= array_sum($array)){
echo "true";
// return true
} else {
echo "false";
// return false
}
?>
it counts the elements of the array, and compares it with the COUNTED trues (array_sum($array)). Then it returns true or false, dependent on result.
You could iterate through the array and set a result to false if any vals are false;
$result = true;
foreach ($array as $v) {
if ($v===false) $result = false;
}
You can use array_filter without callback. In this case all entries of array equal to false will be removed.
if (count(array_filter($array)) == count($array)) echo 'TRUE';
I am trying to search an array and see if a value is contained in it. If the value is in the array then the index of the value in the array will be passed onto be removed from the array.
The problem is array_search returns FALSE if the value is not found, but since false is a boolean it is also treated as 0. When this is passed to the unset to remove the value from the array the value at index 0 will be removed if array_search returned false.
I am fairly sure it will need to be put into an if statement but how will I handle the response if both an integer and a boolean can both be returned?
Current Code:
$pos = array_search($value, $array);
unset($array[$pos]);
PHP Doc says..
This function may return Boolean FALSE, but may also return a
non-Boolean value which evaluates to FALSE. Please read the section on
Booleans for more information. Use the === operator for testing the
return value of this function.
So you need to do like this
<?php
$arr = [1,2,3];
$pos = array_search(4, $arr);
if($pos!==false)
{
unset($arr[$pos]);
}
print_r($arr);
OUTPUT
Array
(
[0] => 1
[1] => 2
[2] => 3
)
As you can see the first index is retained.
try this
if($pos !== false)
{
// do your work to unset
}
note !== in above code
$x !== $y is True if $x is not equal to $y, or they are not of the same type
You can try this script, hope this will help you...
if(in_array($value, $array)){
$pos = array_search($value, $array);
unset($array[$pos]);
}
I need to check if all values in an array equal the same thing.
For example:
$allValues = array(
'true',
'true',
'true',
);
If every value in the array equals 'true' then I want to echo 'all true'. If any value in the array equals 'false' then I want to echo 'some false'
Any idea on how I can do this?
All values equal the test value:
// note, "count(array_flip($allvalues))" is a tricky but very fast way to count the unique values.
// "end($allvalues)" is a way to get an arbitrary value from an array without needing to know a valid array key. For example, assuming $allvalues[0] exists may not be true.
if (count(array_flip($allvalues)) === 1 && end($allvalues) === 'true') {
}
or just test for the existence of the thing you don't want:
if (in_array('false', $allvalues, true)) {
}
Prefer the latter method if you're sure that there's only 2 possible values that could be in the array, as it's much more efficient. But if in doubt, a slow program is better than an incorrect program, so use the first method.
If you can't use the second method, your array is very large, and the contents of the array is likely to have more than 1 value (especially if the 2nd value is likely to occur near the beginning of the array), it may be much faster to do the following:
/**
* Checks if an array contains at most 1 distinct value.
* Optionally, restrict what the 1 distinct value is permitted to be via
* a user supplied testValue.
*
* #param array $arr - Array to check
* #param null $testValue - Optional value to restrict which distinct value the array is permitted to contain.
* #return bool - false if the array contains more than 1 distinct value, or contains a value other than your supplied testValue.
* #assert isHomogenous([]) === true
* #assert isHomogenous([], 2) === true
* #assert isHomogenous([2]) === true
* #assert isHomogenous([2, 3]) === false
* #assert isHomogenous([2, 2]) === true
* #assert isHomogenous([2, 2], 2) === true
* #assert isHomogenous([2, 2], 3) === false
* #assert isHomogenous([2, 3], 3) === false
* #assert isHomogenous([null, null], null) === true
*/
function isHomogenous(array $arr, $testValue = null) {
// If they did not pass the 2nd func argument, then we will use an arbitrary value in the $arr (that happens to be the first value).
// By using func_num_args() to test for this, we can properly support testing for an array filled with nulls, if desired.
// ie isHomogenous([null, null], null) === true
$testValue = func_num_args() > 1 ? $testValue : reset($arr);
foreach ($arr as $val) {
if ($testValue !== $val) {
return false;
}
}
return true;
}
Note: Some answers interpret the original question as (1) how to check if all values are the same, while others interpreted it as (2) how to check if all values are the same and make sure that value equals the test value. The solution you choose should be mindful of that detail.
My first 2 solutions answered #2. My isHomogenous() function answers #1, or #2 if you pass it the 2nd arg.
Why not just compare count after calling array_unique()?
To check if all elements in an array are the same, should be as simple as:
$allValuesAreTheSame = (count(array_unique($allValues, SORT_REGULAR)) === 1);
This should work regardless of the type of values in the array.
Update: Added the SORT_REGULAR flag to avoid implicit type-casting as pointed out by Yann Chabot
Also, you can condense goat's answer in the event it's not a binary:
if (count(array_unique($allvalues)) === 1 && end($allvalues) === 'true') {
// ...
}
to
if (array_unique($allvalues) === array('foobar')) {
// all values in array are "foobar"
}
If your array contains actual booleans (or ints) instead of strings, you could use array_sum:
$allvalues = array(TRUE, TRUE, TRUE);
if(array_sum($allvalues) == count($allvalues)) {
echo 'all true';
} else {
echo 'some false';
}
http://codepad.org/FIgomd9X
This works because TRUE will be evaluated as 1, and FALSE as 0.
You can compare min and max... not the fastest way ;p
$homogenous = ( min($array) === max($array) );
$alltrue = 1;
foreach($array as $item) {
if($item!='true') { $alltrue = 0; }
}
if($alltrue) { echo("all true."); }
else { echo("some false."); }
Technically this doesn't test for "some false," it tests for "not all true." But it sounds like you're pretty sure that the only values you'll get are 'true' and 'false'.
Another option:
function same($arr) {
return $arr === array_filter($arr, function ($element) use ($arr) {
return ($element === $arr[0]);
});
}
Usage:
same(array(true, true, true)); // => true
Answering my method for people searching in 2023.
$arr = [5,5,5,5,5];
$flag = 0;
$firstElement = $arr[0];
foreach($arr as $val){
// CHECK IF THE FIRST ELEMENT DIFFERS FROM ANY OTHER ELEMENT IN THE ARRAY
if($firstElement != $val){
// FIRST MISMATCH FOUND. UPDATE FLAG VALUE AND BREAK OUT OF THE LOOP.
$flag = 1;
break;
}
}
if($flag == 0){
// ALL THE ELEMENTS ARE SAME... DO SOMETHING
}else{
// ALL THE ELEMENTS ARE NOT SAME... DO SOMETHING
}
In an array where all elements are same, it should always be true that all the elements MUST match with the first element of the array. Keeping this logic in mind, we can get the first element of the array and iterate through each element in the array to check for that first element in the loop which does not match with the first element in the array. If found, we will change the flag value and break out of the loop immediately. Else, the loop will continue till it reaches the end. Later, outside the loop, we can use this flag value to determine if all the elements in the array are same or not.
This solution is good for arrays with definite limit of elements (small array). However, I am not sure how good this solution would be for arrays with very large number of elements present considering that we are looping through each and every element to check for the first break even point. Please use this solution at your own convenience and judgement.
$x = 0;
foreach ($allvalues as $a) {
if ($a != $checkvalue) {
$x = 1;
}
}
//then check against $x
if ($x != 0) {
//not all values are the same
}