In Expressions

John Colvin via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Mar 4 09:57:16 PST 2017


On Saturday, 4 March 2017 at 17:11:46 UTC, Andrey wrote:
> Hello, is there any way to using in expression like in python, 
> e.g.
>> if 4 in [1, 3, 4]:
>>     do something
>
> My code in D
>> if (regionAlign in [RegionAlign.top, RegionAlign.bottom]) {
>>    ...
>> }
>
> throws an error:
>> incompatible types for (((cast(Widget)this).regionAlign()) in 
>> ([top, bottom])): 'RegionAlign' and 'RegionAlign[]'

The in operator is defined for associative arrays, but not for 
normal arrays/slices.

You could do this:

import std.algorithm : canFind;
if ([RegionAlign.top, RegionAlign.bottom].canFind(regionAlign)) {
}

Consider using only(RegionAlign.top, RegionAlign.bottom) instead 
of [] to avoid allocating a temporary array.

import std.algorithm : canFind;
if (only(RegionAlign.top, 
RegionAlign.bottom).canFind(regionAlign)) {
}

but to be honest, I would just repeat myself a bit and write

if (regionAlign == RegionAlign.top ||
     regionAlign == RegionAlign.bottom) {
}

If you *really* must have `in`, you could wrap your arrays (or 
other ranges) in this:

import std.range : isInputRange;

struct WithInOp(alias eqPred = "a == b", Range)
if (isInputRange!Range)
{
     Range range;
     alias range this;
     bool opBinaryRight(string op : "in", T)(T rhs)
     {
         import std.algorithm.searching : canFind;
         return range.canFind!eqPred(rhs);
     }
}

auto withInOp(alias eqPred = "a == b", Range)(Range range)
{
     return WithInOp!(eqPred, Range)(range);
}

unittest
{
     auto r = withInOp([1, 2, 4]);
     assert(1 in r);
     assert(3 !in r);
     assert([1, 2] in r);
     assert([2, 2] !in r);

     struct S
     {
         int main, extra;
     }

     auto r2 = withInOp!"a.main == b.main"([S(1, 3), S(2, 4), S(4, 
1)]);
     assert(S(1, 7) in r2);
     assert(S(3, 4) !in r2);
     assert([S(2, -42), S(4, 3)] in r2);
     assert([S(2, -42), S(3, 3)] !in r2);
}


More information about the Digitalmars-d-learn mailing list