Skip to content

Instantly share code, notes, and snippets.

@ericvoid
Created March 19, 2022 20:58
Show Gist options
  • Save ericvoid/4d59ca8fa8980f101c384240d7744b6c to your computer and use it in GitHub Desktop.
Save ericvoid/4d59ca8fa8980f101c384240d7744b6c to your computer and use it in GitHub Desktop.
PHP Chained Comparisons
<?php
function OP_GT($x, $y) { return $x > $y; }
function OP_GTE($x, $y) { return $x >= $y; }
function OP_LT($x, $y) { return $x < $y; }
function OP_LTE($x, $y) { return $x <= $y; }
function OP_NID($x, $y) { return $x !== $y; }
function OP_NEQ($x, $y) { return $x != $y; }
// Checks if items in `$arr` are ascending.
// When `$eq` argument is set to `true`, the function accepts consecutive
// repeated values, like `[1, 2, 2, 3]`.
// If `$arr` is empty, then `false` is returned.
// If `$arr` has one item, then `true` is returned.
function array_is_asc(array $arr, bool $eq=false) : bool {
switch ($n = count($arr)) {
case 0: return false;
case 1: return true;
}
$op = $eq ? 'OP_GT' : 'OP_GTE';
for ($i = 0; $i < $n - 1; $i++)
if (call_user_func($op, $arr[$i], $arr[$i + 1]))
return false;
return true;
}
// Checks if items in `$arr` are descending.
// When `$eq` argument is set to `true`, the function accepts consecutive
// repeated values, like `[3, 2, 2, 1]`.
// If `$arr` is empty, then `false` is returned.
// If `$arr` has one item, then `true` is returned.
function array_is_desc(array $arr, bool $eq=false) : bool {
switch ($n = count($arr)) {
case 0: return false;
case 1: return true;
}
$op = $eq ? 'OP_LT' : 'OP_LTE';
for ($i = 0; $i < $n - 1; $i++)
if (call_user_func($op, $arr[$i], $arr[$i + 1]))
return false;
return true;
}
// Checks if all items in `$arr` are equal to `$val`.
// Set `$strict` to true to use the identical operator `===`.
// If the `$arr` is empty, then `false` is returned.
function array_all_eq_val(array $arr, mixed $val, bool $strict=false) {
if (count($arr) == 0)
return false;
$op = $strict ? 'OP_NID' : 'OP_NEQ';
foreach ($arr as $x)
if (call_user_func($op, $x, $val))
return false;
return true;
}
// Checks if all items in `$arr` are equal.
// Set `$strict` to true to use the identical operator `===`.
// If `$arr` is empty, then `false` is returned.
// If `$arr` has one item, then `true` is returned.
function array_all_eq(array $arr, bool $strict=false) : bool {
switch ($n = count($arr)) {
case 0: return false;
case 1: return true;
}
$op = $strict ? 'OP_NID' : 'OP_NEQ';
for ($i = 0; $i < $n - 1; $i++)
if (call_user_func($op, $arr[$i], $arr[$i + 1]))
return false;
return true;
}
// Checks if all items in `$arr` are unique.
// Set `$strict` to true to use the identical operator `===`.
// If `$arr` is empty, then `false` is returned.
// If `$arr` has one item, then `true` is returned.
function array_all_unique(array $arr, bool $strict=false) : bool {
switch ($n = count($arr)) {
case 0: return false;
case 1: return true;
}
if (!$strict) {
return count(array_unique($arr)) === $n;
}
$tmp = [];
foreach ($arr as $x)
if (!in_array($x, $tmp, strict: true))
$tmp[] = $x;
return count($tmp) === $n;
}

Python has a synthax to chain comparison operators. For example:

    if x > y > z:
        print('foo')

    if x < y < z:
        print('bar')

    if x == y == z:
        print('baz')

But PHP doesn't offer a syntax like this.

So I implemented a few functions to emulate this kind of comparison.

Examples:

To check if the items in the array are ascending, like x < y < z in Python:

    if (array_is_asc([$x, $y, $z]))
        // ...

    // To accept consecutive equal values (like `x <= y <= z`).
    if (array_is_asc([$x, $y, $y, $z], eq: true))
        // ...

    // It makes the code cleaner when used with multiple values
    // (althoug less efficient).
    if (array_is_asc([$kMin, $x, $y, $kMid, $z, $w, $kMax]))
        // ...

To check if the items in the array are descending, like x > y > z in Python:

    if (array_is_desc([$x, $y, $z]))
        // ...

    // To accept consecutive equal values (like `x >= y >= z`).
    if (array_is_desc([$x, $y, $y, $z], eq: true))
        // ...

To check if all items in an array equals to a value, like x == y == z == 1 in Python:

    if (array_all_eq_val([$x, $y, $z], 1))
        // ...

    // To use the identical operator `===`
    if (array_all_eq_val([$x, $y, $z], 1, strict: true))
        // ...

To check if all items in an array are the same, like x == y == z in Python:

    if (array_all_eq([$x, $y, $z]))
        // ...

    // To use the indentical operator `===`
    if (array_all_eq([$x, $y, $z], strict: true))
        // ...

To check if all items in an array are unique, like len(x) == len(set(x)) in Python:

    if (array_all_unique([$x, $y, $z]))
        // ...

    // To use the identical operator `===`
    if (array_all_unique([$x, $y, $z], strict: true))
        // ...

Disclaimer

Use as you wish, don't blame me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment