Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 04, 2017 In Expressions | ||||
---|---|---|---|---|
| ||||
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[]' |
March 04, 2017 Re: In Expressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | 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); } |
March 04, 2017 Re: In Expressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | 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 reason this is disallowed for normal arrays is that finding a key in an array is O(n) while finding a key in an associative array is O(1). Rather than let users unknowingly write code that looks the same but is far slower for arrays, D doesn't allow this. You can use std.algorithm.among, however. import std.algorithm; if (regionAlign.among!(RegionAlign.top, RegionAlign.bottom)) { //etc. } http://dlang.org/phobos/std_algorithm_comparison.html#.among |
March 04, 2017 Re: In Expressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Saturday, 4 March 2017 at 17:57:16 UTC, John Colvin wrote:
> but to be honest, I would just repeat myself a bit and write
>
> if (regionAlign == RegionAlign.top ||
> regionAlign == RegionAlign.bottom) {
> }
That's exactly what I did, just wondered - how to do such a thing.
Thank's for the detailed explanation.
|
March 05, 2017 Re: In Expressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | On Saturday, 4 March 2017 at 19:31:46 UTC, Andrey wrote:
> On Saturday, 4 March 2017 at 17:57:16 UTC, John Colvin wrote:
>> but to be honest, I would just repeat myself a bit and write
>>
>> if (regionAlign == RegionAlign.top ||
>> regionAlign == RegionAlign.bottom) {
>> }
>
> That's exactly what I did, just wondered - how to do such a thing.
> Thank's for the detailed explanation.
Run this through DUB:
```
/+dub.sdl:
name "dub_script"
dependency "iz" version="~master"
+/
module dub_script;
enum RegionAlign
{
top, botttom, left, right
}
import iz.enumset;
alias Set = EnumSet!(RegionAlign, Set8);
void main(string[] args)
{
with(RegionAlign)
{
Set set = [top, left];
assert(top in set);
assert(left in set);
}
}
```
iz.enumset.EnumSet seems to be what you need. (assuming Region align is a named enum...)
|
Copyright © 1999-2021 by the D Language Foundation