March 11, 2008
okibi wrote:
> I've looked all over the site but can't seem to find if D supports any kind of like IN statement for comparisons. For example, I can do the following in SQL:
> 
> select *
> from table
> where value in (1,2,3)
> 
> And it will compare it to 1, 2, and 3. Is this possible to do within D's if statement? I hate to go about it as such:
> 
> if (value == 1 || value == 2 || value == 3)
>     dosomething();
> 
> Just seems like this could be written better. Can anyone give me any pointers?
> 
> Thanks!

bool includes (T) (T[] array, item) {
  foreach (i; array) {
    if ( item == i) { return true; }
  }

  return false;
}

if (["a", "b", "c"].includes("a")) {
  doSomething();
}

untested, and almost the same as Frank's, just a tad more Ruby-ish. ;)
March 11, 2008
downs wrote:
> Bill Baxter wrote:
>> okibi wrote:
>>> I've looked all over the site but can't seem to find if D supports any
>>> kind of like IN statement for comparisons. For example, I can do the
>>> following in SQL:
>>>
>>> select *
>>> from table
>>> where value in (1,2,3)
>>>
>>> And it will compare it to 1, 2, and 3. Is this possible to do within
>>> D's if statement? I hate to go about it as such:
>>>
>>> if (value == 1 || value == 2 || value == 3)
>>>     dosomething();
>>>
>>> Just seems like this could be written better. Can anyone give me any
>>> pointers?
>> I can point you to a bunch of discussions where certain people argued
>> tooth and nail that  "if(value in [1,2,3])" should mean
>> "if(value==0||value==1||value==2)", leading basically to a stalemate.
>> So, no.  Nothing like that is in the language.
>>
>> But you can write a little "contains" function that will do the trick.
>>
>> Or ask Downs how to make "if(x /In/ [1,2,3])" work.
>>
>> --bb
> 
> There's a better way actually.
> 
> import std.stdio;
> 
> // bottom-inclusive, top-exclusive, like slices.
> struct _Range(T) {
>   T from, to;
>   bool opIn_r(U)(U u) {
>     return u < to && u !< from;
>   }
> }
> 
> struct Range {
>   static _Range!(T) opSlice(T, U)(T from, U to) {
>     return _Range!(T)(from, to);
>   }
> }
> 
> void main() {
>   writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]);
> }
> 
> Have funs!

What?! Dost mine eyes deceive me?  Downs just gave up an opportunity to proselytize about his infix operators?
This is sure a sign of the end times, my friends.

--bb
March 11, 2008
Bill Baxter wrote:
> downs wrote:
>> Bill Baxter wrote:
>>> okibi wrote:
>>>> I've looked all over the site but can't seem to find if D supports any kind of like IN statement for comparisons. For example, I can do the following in SQL:
>>>>
>>>> select *
>>>> from table
>>>> where value in (1,2,3)
>>>>
>>>> And it will compare it to 1, 2, and 3. Is this possible to do within D's if statement? I hate to go about it as such:
>>>>
>>>> if (value == 1 || value == 2 || value == 3)
>>>>     dosomething();
>>>>
>>>> Just seems like this could be written better. Can anyone give me any pointers?
>>> I can point you to a bunch of discussions where certain people argued tooth and nail that  "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no.  Nothing like that is in the language.
>>>
>>> But you can write a little "contains" function that will do the trick.
>>>
>>> Or ask Downs how to make "if(x /In/ [1,2,3])" work.
>>>
>>> --bb
>>
>> There's a better way actually.
>>
>> import std.stdio;
>>
>> // bottom-inclusive, top-exclusive, like slices.
>> struct _Range(T) {
>>   T from, to;
>>   bool opIn_r(U)(U u) {
>>     return u < to && u !< from;
>>   }
>> }
>>
>> struct Range {
>>   static _Range!(T) opSlice(T, U)(T from, U to) {
>>     return _Range!(T)(from, to);
>>   }
>> }
>>
>> void main() {
>>   writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]);
>> }
>>
>> Have funs!
> 
> What?! Dost mine eyes deceive me?  Downs just gave up an opportunity to
> proselytize about his infix operators?
> This is sure a sign of the end times, my friends.
> 
> --bb

Um.

`in` already is an infix operator :)

 --downs
March 11, 2008
downs wrote:
> Bill Baxter wrote:
>> downs wrote:
>>> Bill Baxter wrote:
>>>> okibi wrote:
>>>>> I've looked all over the site but can't seem to find if D supports any
>>>>> kind of like IN statement for comparisons. For example, I can do the
>>>>> following in SQL:
>>>>>
>>>>> select *
>>>>> from table
>>>>> where value in (1,2,3)
>>>>>
>>>>> And it will compare it to 1, 2, and 3. Is this possible to do within
>>>>> D's if statement? I hate to go about it as such:
>>>>>
>>>>> if (value == 1 || value == 2 || value == 3)
>>>>>     dosomething();
>>>>>
>>>>> Just seems like this could be written better. Can anyone give me any
>>>>> pointers?
>>>> I can point you to a bunch of discussions where certain people argued
>>>> tooth and nail that  "if(value in [1,2,3])" should mean
>>>> "if(value==0||value==1||value==2)", leading basically to a stalemate.
>>>> So, no.  Nothing like that is in the language.
>>>>
>>>> But you can write a little "contains" function that will do the trick.
>>>>
>>>> Or ask Downs how to make "if(x /In/ [1,2,3])" work.
>>>>
>>>> --bb
>>> There's a better way actually.
>>>
>>> import std.stdio;
>>>
>>> // bottom-inclusive, top-exclusive, like slices.
>>> struct _Range(T) {
>>>   T from, to;
>>>   bool opIn_r(U)(U u) {
>>>     return u < to && u !< from;
>>>   }
>>> }
>>>
>>> struct Range {
>>>   static _Range!(T) opSlice(T, U)(T from, U to) {
>>>     return _Range!(T)(from, to);
>>>   }
>>> }
>>>
>>> void main() {
>>>   writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]);
>>> }
>>>
>>> Have funs!
>> What?! Dost mine eyes deceive me?  Downs just gave up an opportunity to
>> proselytize about his infix operators?
>> This is sure a sign of the end times, my friends.
>>
>> --bb
> 
> Um.
> 
> `in` already is an infix operator :)
> 
>  --downs

Yes, but it doesn't work!

--bb
March 11, 2008
Bill Baxter wrote:
> downs wrote:
>> Bill Baxter wrote:
>>> downs wrote:
>>>> Bill Baxter wrote:
>>>>> okibi wrote:
>>>>>> I've looked all over the site but can't seem to find if D supports
>>>>>> any
>>>>>> kind of like IN statement for comparisons. For example, I can do the
>>>>>> following in SQL:
>>>>>>
>>>>>> select *
>>>>>> from table
>>>>>> where value in (1,2,3)
>>>>>>
>>>>>> And it will compare it to 1, 2, and 3. Is this possible to do within D's if statement? I hate to go about it as such:
>>>>>>
>>>>>> if (value == 1 || value == 2 || value == 3)
>>>>>>     dosomething();
>>>>>>
>>>>>> Just seems like this could be written better. Can anyone give me any pointers?
>>>>> I can point you to a bunch of discussions where certain people argued tooth and nail that  "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no.  Nothing like that is in the language.
>>>>>
>>>>> But you can write a little "contains" function that will do the trick.
>>>>>
>>>>> Or ask Downs how to make "if(x /In/ [1,2,3])" work.
>>>>>
>>>>> --bb
>>>> There's a better way actually.
>>>>
>>>> import std.stdio;
>>>>
>>>> // bottom-inclusive, top-exclusive, like slices.
>>>> struct _Range(T) {
>>>>   T from, to;
>>>>   bool opIn_r(U)(U u) {
>>>>     return u < to && u !< from;
>>>>   }
>>>> }
>>>>
>>>> struct Range {
>>>>   static _Range!(T) opSlice(T, U)(T from, U to) {
>>>>     return _Range!(T)(from, to);
>>>>   }
>>>> }
>>>>
>>>> void main() {
>>>>   writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]);
>>>> }
>>>>
>>>> Have funs!
>>> What?! Dost mine eyes deceive me?  Downs just gave up an opportunity to
>>> proselytize about his infix operators?
>>> This is sure a sign of the end times, my friends.
>>>
>>> --bb
>>
>> Um.
>>
>> `in` already is an infix operator :)
>>
>>  --downs
> 
> Yes, but it doesn't work!
> 
> --bb

Curious.

Works here, GDC 1.028 / 4.1.2

What are you using?

 --downs
March 11, 2008
Reply to Downs,

> Bill Baxter wrote:
> 
>> downs wrote:
>> 
>>> 
>>> `in` already is an infix operator :)
>>> 
>>> --downs
>>> 
>> Yes, but it doesn't work!
>> 
>> --bb
>> 
> Curious.
> 
> Works here, GDC 1.028 / 4.1.2
> 
> What are you using?
> 
> --downs
> 

I think he was saying the "in" operator dosn't work / works wrong. As in (a in [0:0, 1:2, 2:4, 3:6]) == (0<= a <=4) rather than (a==0 || a==2 || a==4 || a==6).


March 11, 2008
BCS wrote:
> Reply to Downs,
> 
>> Bill Baxter wrote:
>>
>>> downs wrote:
>>>
>>>>
>>>> `in` already is an infix operator :)
>>>>
>>>> --downs
>>>>
>>> Yes, but it doesn't work!
>>>
>>> --bb
>>>
>> Curious.
>>
>> Works here, GDC 1.028 / 4.1.2
>>
>> What are you using?
>>
>> --downs
>>
> 
> I think he was saying the "in" operator dosn't work / works wrong. 

Right, as in "a in [1,2,3]"  is an error, rather than doing what the poster who started this thread expected it to do.

> As in (a in [0:0, 1:2, 2:4, 3:6]) == (0<= a <=4) rather than (a==0 || a==2 || a==4 || a==6).

No that's fine.  If I ask you "is 'ain't' in the the dictionary?" I'm clearly not asking if it appears as a definition.

--bb
March 11, 2008
Bill Baxter wrote:
> BCS wrote:
>> Reply to Downs,
>>
>>> Bill Baxter wrote:
>>>
>>>> downs wrote:
>>>>
>>>>>
>>>>> `in` already is an infix operator :)
>>>>>
>>>>> --downs
>>>>>
>>>> Yes, but it doesn't work!
>>>>
>>>> --bb
>>>>
>>> Curious.
>>>
>>> Works here, GDC 1.028 / 4.1.2
>>>
>>> What are you using?
>>>
>>> --downs
>>>
>>
>> I think he was saying the "in" operator dosn't work / works wrong.
> 
> Right, as in "a in [1,2,3]"  is an error, rather than doing what the poster who started this thread expected it to do.
> 

To give an example of W's stance ..

Say you have a book with four pages.

The first page contains the number 15, the second page 16 the third 23 and the fourth 42.

Now, if I ask "3 in book", do I mean "is the page 3 in the book" (index) or "is the number 3 in the book" (value)?

There's precedence in the D language for the first case, because `in` for AAs also checks against index (key) and not value.

However, checking against value would arguably be more useful :)

In the absence of a consensus, and because a case could be made for both possibilities, it was decided to leave it out for now.

That should about sum it up.

 --downs
March 11, 2008
downs wrote:
> Bill Baxter wrote:
>> BCS wrote:
>>> Reply to Downs,
>>>
>>>> Bill Baxter wrote:
>>>>
>>>>> downs wrote:
>>>>>
>>>>>> `in` already is an infix operator :)
>>>>>>
>>>>>> --downs
>>>>>>
>>>>> Yes, but it doesn't work!
>>>>>
>>>>> --bb
>>>>>
>>>> Curious.
>>>>
>>>> Works here, GDC 1.028 / 4.1.2
>>>>
>>>> What are you using?
>>>>
>>>> --downs
>>>>
>>> I think he was saying the "in" operator dosn't work / works wrong. 
>> Right, as in "a in [1,2,3]"  is an error, rather than doing what the
>> poster who started this thread expected it to do.
>>
> 
> To give an example of W's stance ..
> 
> Say you have a book with four pages.
> 
> The first page contains the number 15, the second page 16 the third 23 and the fourth 42.
> 
> Now, if I ask "3 in book", do I mean "is the page 3 in the book" (index) or "is the number 3 in the book" (value)?
> 
> There's precedence in the D language for the first case, because `in` for AAs also checks against index (key) and not value.
> 
> However, checking against value would arguably be more useful :)
> 
> In the absence of a consensus, and because a case could be made for both possibilities, it was decided to leave it out for now.
> 
> That should about sum it up.

Yes, that sums it up quite nicely.

--bb
March 11, 2008
downs wrote:
> Bill Baxter wrote:
>> okibi wrote:
>>> I've looked all over the site but can't seem to find if D supports any
>>> kind of like IN statement for comparisons. For example, I can do the
>>> following in SQL:
>>>
>>> select *
>>> from table
>>> where value in (1,2,3)
>>>
>>> And it will compare it to 1, 2, and 3. Is this possible to do within
>>> D's if statement? I hate to go about it as such:
>>>
>>> if (value == 1 || value == 2 || value == 3)
>>>     dosomething();
>>>
>>> Just seems like this could be written better. Can anyone give me any
>>> pointers?
>> I can point you to a bunch of discussions where certain people argued
>> tooth and nail that  "if(value in [1,2,3])" should mean
>> "if(value==0||value==1||value==2)", leading basically to a stalemate.
>> So, no.  Nothing like that is in the language.
>>
>> But you can write a little "contains" function that will do the trick.
>>
>> Or ask Downs how to make "if(x /In/ [1,2,3])" work.
>>
>> --bb
> 
> There's a better way actually.
> 
> import std.stdio;
> 
> // bottom-inclusive, top-exclusive, like slices.
> struct _Range(T) {
>   T from, to;
>   bool opIn_r(U)(U u) {
>     return u < to && u !< from;
>   }
> }
> 
> struct Range {
>   static _Range!(T) opSlice(T, U)(T from, U to) {
>     return _Range!(T)(from, to);
>   }
> }
> 
> void main() {
>   writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]);
> }
> 
> Have funs!
> 
>  --downs


Downs seems to have misunderstood the request, but his suggestion can be adapted to do what the OP wanted, and without the high cost of constructing an associative array on the fly:

import std.stdio;

struct _Set(T) {
    T[] _set;
    bool opIn_r(U)(U u) {
        foreach(v; _set) {
            if (v==u) return true;
        }
        return false;
    }
}

struct Set {
    static _Set!(T) opIndex(T)(T[] x ...) {
        return _Set!(T)(x);
    }
    // or this
    static _Set!(T) opCall(T)(T[] x ...) {
        return _Set!(T)(x);
    }
}

void main() {
    // doesn't work because of template deduction bug :-(
    //writefln(3 in Set[2,7,4], " -- ", 4 in Set[2,7,4]);

    // ok
    writefln(3 in Set([2,7,4]), " -- ", 4 in Set([2,7,4]));
}