Nick
Nick

Reputation: 1999

Check if all values in array are the same

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?

Upvotes: 74

Views: 119682

Answers (9)

RedStar Entertainment
RedStar Entertainment

Reputation: 440

Answering my method for people searching in 2023.

$arr = [5,5,5,5,5];
$flag = 0;
$firstElement = $arr[0];

if(count($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.

Upvotes: -1

Werner
Werner

Reputation: 3663

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

Upvotes: 46

goat
goat

Reputation: 31854

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.

Upvotes: 138

user1718888
user1718888

Reputation: 331

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"
}

Upvotes: 18

quazardous
quazardous

Reputation: 876

You can compare min and max... not the fastest way ;p

$homogenous = ( min($array) === max($array) );

Upvotes: 6

Wayne
Wayne

Reputation: 60424

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

Upvotes: 2

bfavaretto
bfavaretto

Reputation: 71939

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.

Upvotes: 15

Norse
Norse

Reputation: 5757

$x = 0;
foreach ($allvalues as $a) {
   if ($a != $checkvalue) {
      $x = 1;
   }
}

//then check against $x
if ($x != 0) {
   //not all values are the same
}

Upvotes: -3

octern
octern

Reputation: 4868

$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'.

Upvotes: 0

Related Questions