Most Efficient Way to Compare a Variable to Multiple Values

Most efficient way to compare a variable to multiple values?

If the values you want to check are sufficiently small, you could create a bit mask of the values that you seek and then check for that bit to be set.

Suppose, you care about a couple of groups.

static const unsigned values_group_1 = (1 << 1) | (1 << 2) | (1 << 3);
static const unsigned values_group_2 = (1 << 4) | (1 << 5) | (1 << 6);
static const unsigned values_group_3 = (1 << 7) | (1 << 8) | (1 << 9);
if ((1 << value_to_check) & values_group_1) {
// You found a match for group 1
}
if ((1 << value_to_check) & values_group_2) {
// You found a match for group 2
}
if ((1 << value_to_check) & values_group_3) {
// You found a match for group 3
}

This approach works best for values that don't exceed the natural size your CPU likes to work with. This would typically be 64 in modern times, but may vary depending upon the specifics of your environment.

Best way to compare variable to multiple integers in javascript [duplicate]

You can use an array and then validate that id using the function includes.

const id = 2;const array = [1, 2, 3];
if (array.includes(id)) console.log("I'm in!");

What's the prettiest way to compare one value against multiple values? [duplicate]

Don't try to be too sneaky, especially when it needlessly affects performance.
If you really have a whole heap of comparisons to do, just format it nicely.

if (foobar === foo ||
foobar === bar ||
foobar === baz ||
foobar === pew) {
//do something
}

Concise way to compare against multiple values [duplicate]

With a regex:

if (/^(something|nothing|anything|everything)$/.exec('jesus')) alert('Who cares?');​

Or the opposite:

/^(something|nothing|anything|everything)$/.exec('jesus')||alert('Who cares?');​

[Update] Even shorter ;-)

if (/^(some|no|any|every)thing$/.exec('jesus')) alert('Who cares?');​

How to test multiple variables for equality against a single value?

You misunderstand how boolean expressions work; they don't work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:

if x == 1 or y == 1 or z == 1:

x and y are otherwise evaluated on their own (False if 0, True otherwise).

You can shorten that using a containment test against a tuple:

if 1 in (x, y, z):

or better still:

if 1 in {x, y, z}:

using a set to take advantage of the constant-cost membership test (i.e. in takes a fixed amount of time whatever the left-hand operand is).

Explanation

When you use or, python sees each side of the operator as separate expressions. The expression x or y == 1 is treated as first a boolean test for x, then if that is False, the expression y == 1 is tested.

This is due to operator precedence. The or operator has a lower precedence than the == test, so the latter is evaluated first.

However, even if this were not the case, and the expression x or y or z == 1 was actually interpreted as (x or y or z) == 1 instead, this would still not do what you expect it to do.

x or y or z would evaluate to the first argument that is 'truthy', e.g. not False, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context).

So for the values x = 2; y = 1; z = 0, x or y or z would resolve to 2, because that is the first true-like value in the arguments. Then 2 == 1 would be False, even though y == 1 would be True.

The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3 would fail for the same reasons. Use x == 1 or x == 2 or x == 3 or x in {1, 2, 3}.

Concise way to compare a variable against multiple values [duplicate]

You can use in operator:

for i in range(10):
if i in (3, 5) or math.sqrt(i) in (3, 5):
numbers.append(i)

or in case you expect each of the calculations to be in the same group of results, you can use any()

results = [1, 2, ..., too long list for single line]
expected = (3, 5)

if any([result in expected for result in results]):
print("Found!")

Just a minor nitpick, sqrt will most likely return a float sooner or later and this approach will be silly in the future, therefore math.isclose() or others will help you not to encounter float "bugs" such as:

2.99999999999999 in (3, 5)  # False

which will cause your condition to fail.

In PHP, is there a short way to compare a variable to multiple values?

in_array() is what I use

if (in_array($variable, array('one','two','three'))) {

Lua - Most resource efficient way to compare a variable to a fixed list of values

Tables can be used as sets:

interesting = {
["1"] = true, ["16"] = true, ["58"] = true
}

if interesting[ID] then
-- ...
end

While it eats more memory (80 bytes per empty table plus 32 bytes (IIRC, on x86_64) per entry (while rounding the number of entries up to the next power of two) vs. 16 bytes per comparison plus storage for the value that you compare) the chain of comparisons happens in C and is therefore faster than a chain of comparisons as a sequence of Lua instructions (at least once things get larger).

For small numbers of values, this doesn't really matter. (If you are CPU-bound and this is very important in your case, measure in the context of your program and see what performs better. Don't put too much weight on micro-benchmarks with this – cache behavior in particular might produce funny effects here.)

For large numbers of comparisons, this is the right approach. It's also more flexible than if-then-else chains. (You can change things at runtime without reloading code.)

Also note that the value you use to anchor an element in the set doesn't really matter, so a relatively common idiom (especially for input handling) is putting the action as a function into the table:

keybindings = {
left = function() Player:move_left( ) end,
right = function() Player:move_right( ) end,
up = function() Player:jump( ) end,
-- ...
}

function onKey( k )
local action = keybindings[k]
if action then action( ) end
end

While this certainly is slower than a direct comparison and inline code, speed is essentially irrelevant here (generally happens much less often than ~100x per second) and flexibility is of high value.



Related Topics



Leave a reply



Submit