检查平面数组是否完全由 true 值或全部由 false 值组成

发布于 2024-11-26 19:17:04 字数 399 浏览 0 评论 0原文

如何检查数组中的所有元素是否都为 true,或者是否所有元素都为 false

理想情况下,我试图避免使用非常长的 if 表达式。

array('a'=> true, 'b'=> true, ...)

澄清预期结果:

  • 如果数组同时具有 truefalse 值,则不返回任何内容。
  • 如果数组只有 true 值,则返回 true
  • 如果数组只有 false 值,则返回 false

How can I check if all elements in an array are true, or if all elements are false?

Ideally, I am trying to avoid a really long if expression.

array('a'=> true, 'b'=> true, ...)

To clarify the expected result:

  • If the array has both true and false values return nothing.
  • If the array has only true values return true.
  • If the array has only false values return false.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

塔塔猫 2024-12-03 19:17:04
if(count(array_unique($your_array)) === 1)  
  return current($your_array);

else return;
if(count(array_unique($your_array)) === 1)  
  return current($your_array);

else return;
携余温的黄昏 2024-12-03 19:17:04

您可以使用 in_array

例如。对于所有真实的:

if(in_array(false, $array, true) === false){
    return true;
}
else if(in_array(true, $array, true) === false){
    return false;
}
else{
     return 'nothing';
}

You could use in_array

Ex. for all true:

if(in_array(false, $array, true) === false){
    return true;
}
else if(in_array(true, $array, true) === false){
    return false;
}
else{
     return 'nothing';
}
德意的啸 2024-12-03 19:17:04

可以使用 array_product,如 php.net 所示在评论中

$check[] = boolval(TRUE);
$check[] = boolval(1);
$check[] = boolval(FALSE);
$check[] = boolval(0);

$result = (bool) array_product($check);
// $result is set to FALSE because only two of the four values evaluated to TRUE

One can use array_product as demonstrated at php.net in a comment:

$check[] = boolval(TRUE);
$check[] = boolval(1);
$check[] = boolval(FALSE);
$check[] = boolval(0);

$result = (bool) array_product($check);
// $result is set to FALSE because only two of the four values evaluated to TRUE
夏雨凉 2024-12-03 19:17:04

这个问题很古老,但没关系。我想对不同的方法进行基准测试。 in_array() 方法性能最佳,因为它可能不需要遍历整个数组。 (最后只有一个唯一布尔值的可能性很低,但即使这样它也表现良好。)

这里没有提到的一种方法是 array_sum($array),它返回 0< /code> 如果所有值都是 false,则 1+ 如果某处有 true 值。与 array_filter 方法一样,它不会告诉您两者是否都存在,但对于查明是否有任何内容 true 很有用。我还添加了一个基本的 foreach 检查混合或全部真/假,以及一个 in_array 只检查是否有任何内容是 true (如 <代码>*_bin 下面)。

这是基准。每个案例使用 10、100 或 1000 个随机布尔值的数组迭代 100000 次;再次使用 9、99 和 999 个相同的布尔值,最后一个是唯一的(为 in_array 提供完整的迭代时间)。测试的前三项检查会产生请求的 true/false/both 结果,其余四项仅检查是否存在 true 值。


随机布尔值

  • in_array:10 个布尔值 = 0.16 秒
  • foreach:10 个布尔值 = 0.122 秒
  • array_unique:10 个布尔值 = 0.274 秒
  • foreach_bin强>: 10 布尔 = 0.095 秒
  • in_array_bin:10 个布尔值 = 0.073 秒
  • array_sum:10 个布尔值 = 0.074 秒
  • array_filter:10 个布尔值 = 0.118 秒

  • in_array : 100 布尔值 = 0.153 秒
  • foreach: 100布尔值 = 0.122 秒
  • array_unique:100 布尔值 = 2.3451 秒
  • foreach_bin:100 布尔值 = 0.094 秒
  • in_array_bin:100 布尔值 = 0.074 秒
  • array_sum :100 布尔 = 0.126 秒
  • array_filter:100 个布尔 = 0.228 秒

  • in_array:1000 个布尔 = 0.154 秒
  • foreach:1000 个布尔 = 0.149 秒
  • array_unique: 1000 布尔 = 32.6659 秒(!!)
  • foreach_bin:1000 个布尔值 = 0.075 秒
  • in_array_bin:1000 个布尔值 = 0.074 秒
  • array_sum:1000 个布尔值 = 0.8771 秒
  • array_filter :1000 个布尔 = 1.4021 秒

最后布尔值差异

  • in_array:10 个布尔值 = 0.152 秒
  • foreach:10 个布尔值 = 0.342 秒
  • array_unique:10 个布尔值 = 0.269 秒
  • foreach_bin强>: 10 布尔 = 0.074 秒
  • in_array_bin:10 个布尔值 = 0.076 秒
  • array_sum:10 个布尔值 = 0.074 秒
  • array_filter:10 个布尔值 = 0.121 秒

  • in_array : 100 布尔值 = 0.159 秒
  • foreach: 100 bools = 2.8072 秒
  • array_unique:100 bools = 2.7702 秒
  • foreach_bin:100 bools = 0.074 秒
  • in_array_bin:100 bools = 0.09 秒
  • array_sum :100 布尔 = 0.118 秒
  • array_filter:100 个布尔 = 0.248 秒

  • in_array:1000 个布尔 = 0.312 秒
  • foreach:1000 个布尔 = 27.5256 秒
  • array_unique: 1000 布尔 = 42.1594秒
  • foreach_bin:1000 个布尔 = 0.074 秒
  • in_array_bin:1000 个布尔 = 0.24 秒
  • array_sum:1000 个布尔 = 0.555 秒
  • array_filter:1000 个布尔 = 1.3601 秒

然后,总结一下。 array_unique 方式清楚地保留了尾部,不要用于大型数组或大量数组! foreach 方式比 in_array 稍有优势,但遗憾的是代码并不那么优雅。 array_sum 方式与较小(<100)数组的“if true”检查相同。 (我挖掘了 array_sum($array) > 0 中的简单性。) array_filter 方式稍微落后于 in_array 和 foreach 。当只有最后一个值不同时,foreacharray_unique 都会把它拖得很糟糕。

最后,foreach 函数带来了好心情。非常可读。 事实就在那里!


function foreach_truth_test($array)
{   
    $trues = $falses = false;

    foreach($array as $val) {
        if ($val === true) {
            $trues = true;
        } elseif ($val === false) {
            $falses = true;
        }
        if ($trues === true && $falses === true) {
            return 'both'; // Enough information.
        }
    }

    // Regular Universe
    if ($trues === true && $falses === false) {
        return 'true';
    } // Evil Mirror Universe
    elseif ($trues === false && $falses === true) {
        return 'false';
    } // Intergalactic Void
    else {
        return 'void'; // =^_^=
    }
}

PS 上面可以使用“null”,但这样读起来更有趣。在 Windows 上进行基准测试,因此微时间读数很粗。

This question is ancient, but no matter. I wanted to benchmark the different approaches. The in_array() method performs best since it probably doesn't need to iterate through the whole array. (Odds are low you'd have but one unique boolean at the end, but even then it performs well.)

One approach not mentioned here is array_sum($array), which returns 0 if all values are false, and 1+ if there's a true value somewhere. Like the array_filter approach, it won't tell you if both are present, but is useful for finding out if anything is true. I also added in a basic foreach check for mixed or all true/false, and an in_array that just checks if anything is true (as *_bin below).

So here are the benchmarks. Each case is iterated 100000 times with an array of 10, 100 or 1000 random booleans; and again with 9, 99 and 999 identical booleans, with the last one unique (to have full iteration time for in_array). First three checks tested produce the requested true/false/both result, and the remaining four simply check if a true value is present.


RANDOM BOOLEANS

  • in_array: 10 bools = 0.16 sec
  • foreach: 10 bools = 0.122 sec
  • array_unique: 10 bools = 0.274 sec
  • foreach_bin: 10 bools = 0.095 sec
  • in_array_bin: 10 bools = 0.073 sec
  • array_sum: 10 bools = 0.074 sec
  • array_filter: 10 bools = 0.118 sec

  • in_array: 100 bools = 0.153 sec
  • foreach: 100 bools = 0.122 sec
  • array_unique: 100 bools = 2.3451 sec
  • foreach_bin: 100 bools = 0.094 sec
  • in_array_bin: 100 bools = 0.074 sec
  • array_sum: 100 bools = 0.126 sec
  • array_filter: 100 bools = 0.228 sec

  • in_array: 1000 bools = 0.154 sec
  • foreach: 1000 bools = 0.149 sec
  • array_unique: 1000 bools = 32.6659 sec (!!)
  • foreach_bin: 1000 bools = 0.075 sec
  • in_array_bin: 1000 bools = 0.074 sec
  • array_sum: 1000 bools = 0.8771 sec
  • array_filter: 1000 bools = 1.4021 sec

LAST BOOLEAN DIFFERS

  • in_array: 10 bools = 0.152 sec
  • foreach: 10 bools = 0.342 sec
  • array_unique: 10 bools = 0.269 sec
  • foreach_bin: 10 bools = 0.074 sec
  • in_array_bin: 10 bools = 0.076 sec
  • array_sum: 10 bools = 0.074 sec
  • array_filter: 10 bools = 0.121 sec

  • in_array: 100 bools = 0.159 sec
  • foreach: 100 bools = 2.8072 sec
  • array_unique: 100 bools = 2.7702 sec
  • foreach_bin: 100 bools = 0.074 sec
  • in_array_bin: 100 bools = 0.09 sec
  • array_sum: 100 bools = 0.118 sec
  • array_filter: 100 bools = 0.248 sec

  • in_array: 1000 bools = 0.312 sec
  • foreach: 1000 bools = 27.5256 sec
  • array_unique: 1000 bools = 42.1594 sec
  • foreach_bin: 1000 bools = 0.074 sec
  • in_array_bin: 1000 bools = 0.24 sec
  • array_sum: 1000 bools = 0.555 sec
  • array_filter: 1000 bools = 1.3601 sec

Then, in summary. The array_unique way clearly holds the tail, don't use for large arrays or large volumes of arrays! The foreach way has a slight edge over in_array, but alas the code isn't quite as elegant. The array_sum way is on par with the "if true" checks for smaller (<100) arrays. (I dig the simplicity in array_sum($array) > 0.) The array_filter way lags a bit behind in_array and foreach. When only the last value differs, foreach and array_unique both drag it bad.

Finally, the foreach function for good humors. Very readable. The truth is out there!


function foreach_truth_test($array)
{   
    $trues = $falses = false;

    foreach($array as $val) {
        if ($val === true) {
            $trues = true;
        } elseif ($val === false) {
            $falses = true;
        }
        if ($trues === true && $falses === true) {
            return 'both'; // Enough information.
        }
    }

    // Regular Universe
    if ($trues === true && $falses === false) {
        return 'true';
    } // Evil Mirror Universe
    elseif ($trues === false && $falses === true) {
        return 'false';
    } // Intergalactic Void
    else {
        return 'void'; // =^_^=
    }
}

P.S. Could use 'null' above, but it reads more fun this way around. Benchmarked on Windows so the microtime readings are chunky.

半衬遮猫 2024-12-03 19:17:04

此外,您可以有一个变量列表(不仅仅是值数组)来根据某个值检查所有值。

$var1 = true;
$var2 = true;
$var3 = false;

$isAllVarsTrue = !in_array(false, [$var1, $var2, $var3], true);

var_dump($isAllVarsTrue); //false

More over you can have a list o variables (not only an array of values) to check all the values against a certain value.

$var1 = true;
$var2 = true;
$var3 = false;

$isAllVarsTrue = !in_array(false, [$var1, $var2, $var3], true);

var_dump($isAllVarsTrue); //false
来日方长 2024-12-03 19:17:04

如果您只存储布尔值,请使用以下命令:

$a = array('a'=> true, 'b'=> true, 'c'=>true);
$af = array_filter($a);
if ($af == $a) {
    echo "all true";
}
if (empty($af)) {
    echo "all false";
}

注意:如果数组中有其他值,它们将根据 PHP 可怕的转换规则转换为布尔值。

If you store only booleans, use this:

$a = array('a'=> true, 'b'=> true, 'c'=>true);
$af = array_filter($a);
if ($af == $a) {
    echo "all true";
}
if (empty($af)) {
    echo "all false";
}

Note: if you have other values in the array they will be converted to boolean according to the horrific conversion rules of PHP.

世俗缘 2024-12-03 19:17:04

一个简单的循环就可以了。请注意,如果数组为空,则两个条件都满足(全部为假且全部为真)。由于其他原因,您不会在结果中看到这一点,但您可以自己找出要如何处理此问题。

// Input
$x = array ('a'=>false, 'b'=>false, 'c'=>false);

// Initialization
$anytrue = false;
$alltrue = true;

// Processing
foreach($x as $k=>$v)
{
    $anytrue |= $v;
    $alltrue &= $v;
}

// Display result
if ($alltrue)
  echo 'All elements are true';
elseif (!$anytrue)
  echo 'All elements are false';
else
  echo 'Mixed values';

A simple loop will do. Mind that if the array is empty, both conditions are met (all false and all true). You won't see this in the result, because of the else, but you can find out yourself how you want to handle this.

// Input
$x = array ('a'=>false, 'b'=>false, 'c'=>false);

// Initialization
$anytrue = false;
$alltrue = true;

// Processing
foreach($x as $k=>$v)
{
    $anytrue |= $v;
    $alltrue &= $v;
}

// Display result
if ($alltrue)
  echo 'All elements are true';
elseif (!$anytrue)
  echo 'All elements are false';
else
  echo 'Mixed values';
平定天下 2024-12-03 19:17:04

如果它们都是数组元素,具有真/假值,则使用 array_flip():


$new = array_flip($array);
if (!isset($array[false]) && isset($array[true])) {
...没有假值,并且至少有一个真值
}

对于大型数组来说,这可能会变得昂贵,因此您可能需要尝试 array_unique() 。您将得到一个最多包含两个值的数组(一个 true,一个 false)。


好吧,那是行不通的。简单的霰弹枪方法:

if (in_array($yourarray, false, TRUE)) {
   ... at least one non-true value
}

If they're all array elements, with true/false values, then use array_flip():


$new = array_flip($array);
if (!isset($array[false]) && isset($array[true])) {
... there's no false values, and at least one true value
}

This could get expensive for a large array, so you may want to try array_unique() instead. You'd get an array with at most two values (one true, one false).


Ok, so that wouldn't work. Simple shotgun approach:

if (in_array($yourarray, false, TRUE)) {
   ... at least one non-true value
}
最佳男配角 2024-12-03 19:17:04

使用 for 循环。如果你想检查所有变量是否都是假的,你可以使用 for 循环:一旦找到一个真元素,你就可以打破循环,否则变量都是假的。如果您想检查所有变量是否为真,可以使用相同的方法。

Use a for loop. If you want to check that all variables are false you can use a for loop: once you find a true element you can break the cycle, otherwise variables are all false. Same method you can use if you want to check that all variables are true.

黄昏下泛黄的笔记 2024-12-03 19:17:04
// set default value
$result = false;

foreach ($array as $key => $value) {
    if ($value === true) {
        $result = true;
        break;
    } 
}

// $result is now true if any value was true, otherwise it's false
// set default value
$result = false;

foreach ($array as $key => $value) {
    if ($value === true) {
        $result = true;
        break;
    } 
}

// $result is now true if any value was true, otherwise it's false
梅窗月明清似水 2024-12-03 19:17:04

已更新

!array_filter($arrayValues ?: [0], fn($v) => !$v);

php > var_dump(!array_filter([1, 2, 3] ?: [0], fn($v) => !$v));
bool(true)

php > var_dump(!array_filter([true] ?: [0], fn($v) => !$v));
bool(true)

php > var_dump(!array_filter([true, false] ?: [0], fn($v) => !$v));
bool(false)

php > var_dump(!array_filter([] ?: [0], fn($v) => !$v));
bool(false)

php > var_dump(!array_filter([false] ?: [0], fn($v) => !$v));
bool(false)

Updated

!array_filter($arrayValues ?: [0], fn($v) => !$v);

php > var_dump(!array_filter([1, 2, 3] ?: [0], fn($v) => !$v));
bool(true)

php > var_dump(!array_filter([true] ?: [0], fn($v) => !$v));
bool(true)

php > var_dump(!array_filter([true, false] ?: [0], fn($v) => !$v));
bool(false)

php > var_dump(!array_filter([] ?: [0], fn($v) => !$v));
bool(false)

php > var_dump(!array_filter([false] ?: [0], fn($v) => !$v));
bool(false)
白云悠悠 2024-12-03 19:17:04

我会将我的代码片段嵌入到函数调用中,为那些想要函数式解决方案的人提供帮助。这种通用片段可能最好隐藏在某个帮助文件中。

如果数组为空或包含布尔值的混合,下面的所有代码片段都会返回 null;否则返回出现一次或多次的布尔值。

我最初探索了利用 PHP8.4 的 array_any() 的两次调用的嵌套三元。虽然这试图提供一种具有短路优点的功能风​​格,但它看起来不太干净。美在编码员的眼睛里。 演示

function whollyBool(array $bools): ?bool
{
    return !$bools
        || (
            ($hasTrues = array_any($bools, fn($b) => $b === true))
            && array_any($bools, fn($b) => $b === false)
        )
        ? null
        : $hasTrues;
}

所以我想出了短路 foreach()循环。一种使用空合并,另一种使用按位运算符。选择您更容易理解的一个。

演示

function whollyBool(array $bools): ?bool
{
    foreach ($bools as $b) {
        $first ??= $b;     // cache the first encountered value
        if ($first !== $b) {
            return null;   // return null once a mix is encountered
        }
    }
    return $first ?? null; // use the first value or null if $bools empty
}

演示

function whollyBool(array $bools): ?bool
{
    $hasTrue = null;
    foreach ($bools as $b) {
        $hasTrue |= $b;    // cache 1 (truthy) if ever true else 0 (falsey)
        if ($hasTrue ^ $b) {
            return null;   // return null once a mix is encountered
        }
    }
    return $b ?? $hasTrue; // use the last value or null if $bools empty
}

根据开发人员的喜好,当数组为空或包含布尔值的混合时,可能更喜欢抛出异常。我已经排除了这些实现,但这种方法当然可以内置到这些片段中。

I'll embed my snippets in function calls for those who want a functional style solution. This sort of general use snippet is probably best tucked away in some helper file somewhere.

All snippets below return null if the array is empty or contains a mix of boolean values; otherwise the boolean value that occurs one or more time is returned.

I initially explored a nested ternary leveraging two calls of PHP8.4's array_any(). While this endeavored to provide a functional style with the benefits of short circuiting, it just doesn't look very clean. Beauty is in the eye of the coder. Demo

function whollyBool(array $bools): ?bool
{
    return !$bools
        || (
            ($hasTrues = array_any($bools, fn($b) => $b === true))
            && array_any($bools, fn($b) => $b === false)
        )
        ? null
        : $hasTrues;
}

So I came up with short circuiting foreach() loops. One with null coalescing and another with bitwise operators. Choose the one that you better understand.

Demo

function whollyBool(array $bools): ?bool
{
    foreach ($bools as $b) {
        $first ??= $b;     // cache the first encountered value
        if ($first !== $b) {
            return null;   // return null once a mix is encountered
        }
    }
    return $first ?? null; // use the first value or null if $bools empty
}

Or Demo

function whollyBool(array $bools): ?bool
{
    $hasTrue = null;
    foreach ($bools as $b) {
        $hasTrue |= $b;    // cache 1 (truthy) if ever true else 0 (falsey)
        if ($hasTrue ^ $b) {
            return null;   // return null once a mix is encountered
        }
    }
    return $b ?? $hasTrue; // use the last value or null if $bools empty
}

Depending on developer tastes, it may be favored to throw an exception when the array is empty or contains a mix of boolean values. I've excluded these implementations, but that approach can certainly be built into these snippets.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文