www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Test for element in array

reply Paolo Invernizzi <arathorn NOSPAM_fastwebnet.it> writes:
Hi all,

Someone can suggest me the best way for testing the presence of an 
element in an array?

Coming from python, something like...

if( x in array_of_x && y in array_of_y ){
    ...
}

The workaround, apart from using a simple 'for' loop, is to use an 
associative array, and test for key...

---
Paolo
Jul 13 2006
next sibling parent reply BCS <BCS pathlink.com> writes:
Paolo Invernizzi wrote:
 Hi all,
 
 Someone can suggest me the best way for testing the presence of an 
 element in an array?
 
 Coming from python, something like...
 
 if( x in array_of_x && y in array_of_y ){
    ...
 }
 
 The workaround, apart from using a simple 'for' loop, is to use an 
 associative array, and test for key...
 
 ---
 Paolo

import std.stdio; void main() { int[] a = new int[10]; int j=1; // populate a foreach(int i, inout int k; a) k=i; if({foreach(i;a) if(i==j) return true; return false;}) writef("true\n"); else writef("false\n"); }
Jul 13 2006
parent reply Dave <Dave_member pathlink.com> writes:
BCS wrote:
 Paolo Invernizzi wrote:
 Hi all,

 Someone can suggest me the best way for testing the presence of an 
 element in an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
    ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an 
 associative array, and test for key...

 ---
 Paolo

import std.stdio; void main() { int[] a = new int[10]; int j=1; // populate a foreach(int i, inout int k; a) k=i; if({foreach(i;a) if(i==j) return true; return false;}) writef("true\n"); else writef("false\n"); }

That's a very elegant solution and it should work, but according to my tests it doesn't (darn). It never returns false. Set j = 100 once and give it a try.
Jul 13 2006
parent reply BCS <BCS pathlink.com> writes:
Dave wrote:
 BCS wrote:
 
 Paolo Invernizzi wrote:

 Hi all,

 Someone can suggest me the best way for testing the presence of an 
 element in an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
    ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an 
 associative array, and test for key...

 ---
 Paolo

import std.stdio; void main() { int[] a = new int[10]; int j=1; // populate a foreach(int i, inout int k; a) k=i; if({foreach(i;a) if(i==j) return true; return false;}) writef("true\n"); else writef("false\n"); }

That's a very elegant solution and it should work, but according to my tests it doesn't (darn). It never returns false. Set j = 100 once and give it a try.

Bizarre -- if({foreach(i;a) if(i==j) return true; return false;}) ++ if({foreach(i;a) if(i==j) return true; return false;}()) this fixes it. WT... Oh. {return false;}.typeof == bool delegate() {return false;}().typeof == bool
Jul 13 2006
next sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
BCS wrote:
 Dave wrote:
 
 BCS wrote:

 Paolo Invernizzi wrote:

 Hi all,

 Someone can suggest me the best way for testing the presence of an 
 element in an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
    ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an 
 associative array, and test for key...

 ---
 Paolo

import std.stdio; void main() { int[] a = new int[10]; int j=1; // populate a foreach(int i, inout int k; a) k=i; if({foreach(i;a) if(i==j) return true; return false;}) writef("true\n"); else writef("false\n"); }

That's a very elegant solution and it should work, but according to my tests it doesn't (darn). It never returns false. Set j = 100 once and give it a try.

Bizarre -- if({foreach(i;a) if(i==j) return true; return false;}) ++ if({foreach(i;a) if(i==j) return true; return false;}()) this fixes it. WT... Oh. {return false;}.typeof == bool delegate() {return false;}().typeof == bool

Hmmm. "Lambda properties." Fun. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 13 2006
prev sibling next sibling parent reply "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
BCS wrote:

  if({foreach(i;a) if(i==j) return true; return false;}())

Yeah, this new delegate syntax is cool ! --
Jul 13 2006
parent reply Don Clugston <dac nospam.com.au> writes:
Andrei Khropov wrote:
 BCS wrote:
 
  if({foreach(i;a) if(i==j) return true; return false;}())

Yeah, this new delegate syntax is cool !

Wow! I didn't know you could have a naked {} like that as a void delegate. That is cool. Looks as though D has sucked all the juice out of C++, and is moving onto the scripting languages...
Jul 14 2006
parent reply BCS <BCS pathlink.com> writes:
Don Clugston wrote:
 Andrei Khropov wrote:
 
 BCS wrote:

  if({foreach(i;a) if(i==j) return true; return false;}())

Yeah, this new delegate syntax is cool !

Wow! I didn't know you could have a naked {} like that as a void delegate. That is cool. Looks as though D has sucked all the juice out of C++, and is moving onto the scripting languages...

Not quite naked, without the ending () the type is "bool delegate(void)" a.k.a. always true.
Jul 14 2006
parent Lars Ivar Igesund <larsivar igesund.net> writes:
BCS wrote:

 Don Clugston wrote:
 Andrei Khropov wrote:
 
 BCS wrote:

  if({foreach(i;a) if(i==j) return true; return false;}())

Yeah, this new delegate syntax is cool !

Wow! I didn't know you could have a naked {} like that as a void delegate. That is cool. Looks as though D has sucked all the juice out of C++, and is moving onto the scripting languages...

Not quite naked, without the ending () the type is "bool delegate(void)" a.k.a. always true.

The () is for calling it, {} is fine if you want pass (what I would call naked) a delegate to a function taking delegates as arguments. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Jul 14 2006
prev sibling parent Dave <Dave_member pathlink.com> writes:
BCS wrote:
 Dave wrote:
 BCS wrote:

 Paolo Invernizzi wrote:

 Hi all,

 Someone can suggest me the best way for testing the presence of an 
 element in an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
    ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an 
 associative array, and test for key...

 ---
 Paolo

import std.stdio; void main() { int[] a = new int[10]; int j=1; // populate a foreach(int i, inout int k; a) k=i; if({foreach(i;a) if(i==j) return true; return false;}) writef("true\n"); else writef("false\n"); }

That's a very elegant solution and it should work, but according to my tests it doesn't (darn). It never returns false. Set j = 100 once and give it a try.

Bizarre -- if({foreach(i;a) if(i==j) return true; return false;}) ++ if({foreach(i;a) if(i==j) return true; return false;}()) this fixes it. WT... Oh. {return false;}.typeof == bool delegate() {return false;}().typeof == bool

Ah... Thanks.
Jul 13 2006
prev sibling parent reply "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
Paolo Invernizzi wrote:

 Hi all,
 
 Someone can suggest me the best way for testing the presence of an element in
 an array?
 
 Coming from python, something like...
 
 if( x in array_of_x && y in array_of_y ){
    ...
 }
 
 The workaround, apart from using a simple 'for' loop, is to use an
 associative array, and test for key...
 
 ---
 Paolo

Despite BCS proposed a cool solution I think 'in' should be built-in for usual (non-associative) arrays too. why not? --
Jul 13 2006
parent reply BCS <BCS pathlink.com> writes:
Andrei Khropov wrote:
 Paolo Invernizzi wrote:
 
 
Hi all,

Someone can suggest me the best way for testing the presence of an element in
an array?

Coming from python, something like...

if( x in array_of_x && y in array_of_y ){
   ...
}

The workaround, apart from using a simple 'for' loop, is to use an
associative array, and test for key...

---
Paolo

Despite BCS proposed a cool solution

thanks
 I think 'in' should be built-in for 
 usual (non-associative) arrays too. why not?
 
 

the semantics are backwards, not a killer but its a little inconsistent. With aa, the type of the LHS is the type of the index if(a in b) b[a]; // valid with non-aa, the type of the LHS would be the type of the stored value. The above wont always work for a non-aa. Also which a in b is found? The first? An array of all? The last?
Jul 13 2006
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 13 Jul 2006 16:46:46 -0700, BCS <BCS pathlink.com> wrote:
 Andrei Khropov wrote:
 Paolo Invernizzi wrote:

 Hi all,

 Someone can suggest me the best way for testing the presence of an  
 element in
 an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
   ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an
 associative array, and test for key...

 ---
 Paolo


thanks
 I think 'in' should be built-in for usual (non-associative) arrays too.  
 why not?

the semantics are backwards, not a killer but its a little inconsistent. With aa, the type of the LHS is the type of the index if(a in b) b[a]; // valid with non-aa, the type of the LHS would be the type of the stored value.

True.. (wild idea alert) unless we make it valid to index an array with a value, which in turn returns the index of that value. It would perform a linear search from start to end (or match) therefore returning the 'first' match.
 The above wont always work for a non-aa. Also which a in b is found? The  
 first? An array of all? The last?

In the case of 'in' aren't you just asking "is it in there", in which case it could return the first, or last, doesn't really matter. However, 'in' does return a pointer to the value .. I think returning the first is the least surprising, most useful thing to do. It would also be consistent with the index by value idea above. So, if you want the last match you say: if (a in b.reverse) and if you want the 2nd, 3rd, 4th etc p = (a in b); //gets first p = (a in b[b[*p]..$]); //2nd p = (a in b[b[*p]..$]); //3rd p = (a in b[b[*p]..$]); //4th funky! ;) Regan
Jul 13 2006
prev sibling next sibling parent reply Paolo Invernizzi <arathorn NOSPAM_fastwebnet.it> writes:
BCS wrote:

 the semantics are backwards, not a killer but its a little inconsistent.
 
 With aa, the type of the LHS is the type of the index
 
 if(a in b) b[a]; // valid
 
 with non-aa, the type of the LHS would be the type of the stored value. 
 The above wont always work for a non-aa. Also which a in b is found? The 
 first? An array of all? The last?

I would be satisfied also if it just returns a boolean value, like a simple inclusion test... But for now, I will use the BCS solutions! Thanks! --- Paolo
Jul 14 2006
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Paolo Invernizzi wrote:
 BCS wrote:
 
 the semantics are backwards, not a killer but its a little inconsistent.

 With aa, the type of the LHS is the type of the index

 if(a in b) b[a]; // valid

 with non-aa, the type of the LHS would be the type of the stored 
 value. The above wont always work for a non-aa. Also which a in b is 
 found? The first? An array of all? The last?

I would be satisfied also if it just returns a boolean value, like a simple inclusion test... But for now, I will use the BCS solutions! Thanks! --- Paolo

That's most likely the best solution for the moment. Although, you could generalize it by taking advantage of IFTI and defining this somewhere: # bool contains (T : T[]) (T[] haystack, T needle) { # foreach (x; haystack) { # static if (is(T : Object)) { # if (x is needle) # return true; # } # else { # if (x == needle) # return true; # } # } # return false; # } Then your test would just be: # if (foo.contains(bar)) { # // do stuff # } I think it reads pretty well, even if it isn't quite as "clean" as (bar in foo) in comparison. Which, incidentally, also does read well. -- Chris Nicholson-Sauls
Jul 14 2006
prev sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
BCS wrote:
 Andrei Khropov wrote:
 Paolo Invernizzi wrote:


 Hi all,

 Someone can suggest me the best way for testing the presence of an 
 element in
 an array?

 Coming from python, something like...

 if( x in array_of_x && y in array_of_y ){
   ...
 }

 The workaround, apart from using a simple 'for' loop, is to use an
 associative array, and test for key...

 ---
 Paolo

Despite BCS proposed a cool solution

thanks
 I think 'in' should be built-in for usual (non-associative) arrays 
 too. why not?

the semantics are backwards, not a killer but its a little inconsistent.

Yeah, some think it is some think it isn't, I think it isn't but it is an old discussion and probably one we will never agree on. IMO: normal arrays store *values* which are indexed by a key (index) associative arrays store *keys* and the value is just an additional information about the key. That is only my opinion as some people think that AA's also are about values.
Jul 14 2006
parent reply "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
Ivan Senji wrote:

 
 Yeah, some think it is some think it isn't, I think it isn't but it is an old
 discussion and probably one we will never agree on.
 
 IMO:
 normal arrays store values which are indexed by a key (index)
 associative arrays store keys and the value is just an additional information
 about the key.
 
 That is only my opinion as some people think that AA's also are about values.

AA is also often called dictionary or map (in STL for example). If you speak about some kind of collection where only value (and its presense or absense in the collection) is important it's probably better to call it a set. --
Jul 14 2006
parent reply BCS <BCS pathlink.com> writes:
Andrei Khropov wrote:
 Ivan Senji wrote:
 
 
Yeah, some think it is some think it isn't, I think it isn't but it is an old
discussion and probably one we will never agree on.

IMO:
normal arrays store values which are indexed by a key (index)
associative arrays store keys and the value is just an additional information
about the key.

That is only my opinion as some people think that AA's also are about values.

AA is also often called dictionary or map (in STL for example). If you speak about some kind of collection where only value (and its presense or absense in the collection) is important it's probably better to call it a set.

How about allow void[TYPE]? No values, only keys. void[char[]] whos; ... // fill whos if("Bob" in whos) Hire("Bob"); if("Capone" in whos) whos.remove("Capone"); whos["Bubba"]; // add Bubba auto him = whos["Bubba"]; // can't do that with a void // ( or auto him = whos["Bubba"]; // == bool.true auto who = whos["Capone"]; // == bool.false // )
Jul 14 2006
parent reply Carlos Santander <csantander619 gmail.com> writes:
BCS escribió:
 Andrei Khropov wrote:
 Ivan Senji wrote:


 Yeah, some think it is some think it isn't, I think it isn't but it 
 is an old
 discussion and probably one we will never agree on.

 IMO:
 normal arrays store values which are indexed by a key (index)
 associative arrays store keys and the value is just an additional 
 information
 about the key.

 That is only my opinion as some people think that AA's also are about 
 values.

AA is also often called dictionary or map (in STL for example). If you speak about some kind of collection where only value (and its presense or absense in the collection) is important it's probably better to call it a set.

How about allow void[TYPE]? No values, only keys. void[char[]] whos; .... // fill whos if("Bob" in whos) Hire("Bob"); if("Capone" in whos) whos.remove("Capone"); whos["Bubba"]; // add Bubba auto him = whos["Bubba"]; // can't do that with a void // ( or auto him = whos["Bubba"]; // == bool.true auto who = whos["Capone"]; // == bool.false // )

It was possible some time ago, but it got forbidden. What I've been doing (and I think others too) is: char [] [char []] whos; And set the element to both the key and the value. However, I admit I liked void [T]. -- Carlos Santander Bernal
Jul 14 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 15 Jul 2006 02:46:24 +1000, Carlos Santander  =

<csantander619 gmail.com> wrote:


 It was possible some time ago, but it got forbidden. What I've been  =

 doing (and I think others too) is:

 char [] [char []] whos;

 And set the element to both the key and the value. However, I admit I =

 liked void [T].

Actually I use bool[ char[] ] whos; whos["Capone"] =3D true; -- = Derek Parnell Melbourne, Australia
Jul 14 2006
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Derek Parnell wrote:
 On Sat, 15 Jul 2006 02:46:24 +1000, Carlos Santander  
 <csantander619 gmail.com> wrote:
 
 
 It was possible some time ago, but it got forbidden. What I've been  
 doing (and I think others too) is:

 char [] [char []] whos;

 And set the element to both the key and the value. However, I admit I  
 liked void [T].

Actually I use bool[ char[] ] whos; whos["Capone"] = true;

You can also have a sort of poor-man's multiset with: int[ char[] ] ms; One could easily wrap this with a more multiset-ish interface, but to add an item you just say: ++ms["moo"]; And to remove: if (--ms["moo"] <= 0) ms.remove("moo"); -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 14 2006
parent Paolo Invernizzi <arathorn NOSPAM_fastwebnet.it> writes:
Kirk McDonald wrote:
 Derek Parnell wrote:
 You can also have a sort of poor-man's multiset with:
 
 int[ char[] ] ms;
 
 One could easily wrap this with a more multiset-ish interface, but to 
 add an item you just say:
 
 ++ms["moo"];
 
 And to remove:
 
 if (--ms["moo"] <= 0) ms.remove("moo");
 

That's what I liked from python... with dicts (aka AA) and lists (aka arrays) you can have basically every container you want. And some newbie reading the code can grasp the meaning without loosing himself in a plethora of containers... Now python users are complaining against too much features added in the language... --- Paolo
Jul 15 2006