Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 22, 2014 Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
So I find myself Doing this kind of thing very frequently. I have a Array of Somethings and i want to see if "something specific" is inside the array. I wrote a template for it. but is this the best way to do this kind of thing. I feel like it doesn't help with readability. Is there a better way? Maybe i missed something in the std library. import std.stdio; template FNDR(T){ bool isIn(T Element, T[] Array){ bool rtn=false; foreach(T ArrayElement; Array){ if(Element==ArrayElement){ rtn=true; } } return rtn; } } void main(string[] args) { int[3] stuff=[0,1,2]; if (FNDR!int.isIn(2,stuff)) { writeln("Hello World!"); } } Is there a way maybe to make it look like this? import std.stdio; template FNDR(T){ bool contains(T[] Array,T Element){ bool rtn=false; foreach(T ArrayElement; Array){ if(Element==ArrayElement){ rtn=true; } } return rtn; } } void main(string[] args) { int[3] stuff=[0,1,2]; if (stuff.contains(2)) // Much clean! stuff.FNDR!int.contains(2) doesn't work { writeln("Hello World!"); } } I'm interested in what you guys think? what is the cleanest way to do this? |
April 22, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Taylor Hillegeist Attachments:
| you can use stuff.canFind(2) but sometimes it'd be more convenient to have the other way around (UFCS chains etc); how about: bool isIn(T,T2...)(T needle, T2 haystack) if(__traits(compiles,T.init==T2[0].init)){ foreach(e;haystack){ if(needle==e) return true; } return false; } unittest{ assert(1.isIn(3,1,2) && !4.isIn(3,1,2)); } On Mon, Apr 21, 2014 at 8:25 PM, Taylor Hillegeist via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > So I find myself Doing this kind of thing very frequently. I have a Array of Somethings and i want to see if "something specific" is inside the array. I wrote a template for it. but is this the best way to do this kind of thing. I feel like it doesn't help with readability. Is there a better way? Maybe i missed something in the std library. > > import std.stdio; > > template FNDR(T){ > bool isIn(T Element, T[] Array){ > bool rtn=false; > foreach(T ArrayElement; Array){ > if(Element==ArrayElement){ > rtn=true; > } > } > return rtn; > } > } > > void main(string[] args) > { > int[3] stuff=[0,1,2]; > if (FNDR!int.isIn(2,stuff)) > { > writeln("Hello World!"); > } > } > > > Is there a way maybe to make it look like this? > > import std.stdio; > > template FNDR(T){ > bool contains(T[] Array,T Element){ > bool rtn=false; > foreach(T ArrayElement; Array){ > if(Element==ArrayElement){ > rtn=true; > } > } > return rtn; > } > } > > void main(string[] args) > { > int[3] stuff=[0,1,2]; > if (stuff.contains(2)) // Much clean! stuff.FNDR!int.contains(2) > doesn't work > { > writeln("Hello World!"); > } > } > > I'm interested in what you guys think? what is the cleanest way to do this? > |
April 22, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timothee Cour | On Tuesday, 22 April 2014 at 03:57:33 UTC, Timothee Cour via Digitalmars-d-learn wrote: > you can use stuff.canFind(2) > > but sometimes it'd be more convenient to have the other way around (UFCS > chains etc); > > how about: > > bool isIn(T,T2...)(T needle, T2 haystack) > if(__traits(compiles,T.init==T2[0].init)){ > foreach(e;haystack){ > if(needle==e) return true; > } > return false; > } > unittest{ > assert(1.isIn(3,1,2) && !4.isIn(3,1,2)); > } > I like it! I didn't know you could use templates like that! Question though? why doesn't canFind() work on statically allocated arrays? import std.stdio; import std.algorithm; bool contains(T)( T[] haystack,T needle){ foreach(T e;haystack){ if(needle==e) return true; } return false; } unittest{ assert([3,1,2].contains(1) && ![3,1,2].contains(4)); } void main(string[] args) { int[3] stuff=[0,1,2]; if (stuff.contains(2)) { writeln("Hello World!"); } if (stuff.canFind(2)){ // No compile with stuff -> static writeln("This Also WOrks"); } } > On Mon, Apr 21, 2014 at 8:25 PM, Taylor Hillegeist via Digitalmars-d-learn < > digitalmars-d-learn@puremagic.com> wrote: > >> So I find myself Doing this kind of thing very frequently. I have a Array >> of Somethings and i want to see if "something specific" is inside the >> array. I wrote a template for it. but is this the best way to do this kind >> of thing. I feel like it doesn't help with readability. Is there a better >> way? Maybe i missed something in the std library. >> >> import std.stdio; >> >> template FNDR(T){ >> bool isIn(T Element, T[] Array){ >> bool rtn=false; >> foreach(T ArrayElement; Array){ >> if(Element==ArrayElement){ >> rtn=true; >> } >> } >> return rtn; >> } >> } >> >> void main(string[] args) >> { >> int[3] stuff=[0,1,2]; >> if (FNDR!int.isIn(2,stuff)) >> { >> writeln("Hello World!"); >> } >> } >> >> >> Is there a way maybe to make it look like this? >> >> import std.stdio; >> >> template FNDR(T){ >> bool contains(T[] Array,T Element){ >> bool rtn=false; >> foreach(T ArrayElement; Array){ >> if(Element==ArrayElement){ >> rtn=true; >> } >> } >> return rtn; >> } >> } >> >> void main(string[] args) >> { >> int[3] stuff=[0,1,2]; >> if (stuff.contains(2)) // Much clean! stuff.FNDR!int.contains(2) >> doesn't work >> { >> writeln("Hello World!"); >> } >> } >> >> I'm interested in what you guys think? what is the cleanest way to do this? |
April 22, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Taylor Hillegeist | On 04/21/2014 09:22 PM, Taylor Hillegeist wrote: > Question though? why doesn't canFind() work on statically > allocated arrays? That's an issue all of face from time to time. (Happened to me again last week. :) ) The reason is, algorithms like canFind work with input ranges and fixed-length arrays are not input ranges because they cannot support popFront(), which would reduce their length. The solution is to use a full slice of the array by appending [] to it: if (stuff[].canFind(2)) { // <-- note [] It works because now canFind() operates on a temporary slice (aka dynamic array). Getting back to your original question, std.algorithm.find and canFind() are O(N) algorithms, which is too slow if you already have a sorted range. When you indeed have a sorted range, you can pass it through assumeSorted() to create a SortedRange object so that you can take advantage of O(log N) algorithms like trisect() and friends (one of those friends is contains()): import std.range; void main() { auto arr = [ 1, 2, 3, 3, 4, 5 ]; auto result = arr.assumeSorted.trisect(3); assert(result[0].equal([ 1, 2 ])); assert(result[1].equal([ 3, 3 ])); assert(result[2].equal([ 4, 5 ])); } The search in that program is O(log N). Ali |
April 22, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Taylor Hillegeist | On Mon, 21 Apr 2014 23:25:39 -0400, Taylor Hillegeist <taylorh140@gmail.com> wrote: > So I find myself Doing this kind of thing very frequently. I have a Array of Somethings and i want to see if "something specific" is inside the array. I wrote a template for it. but is this the best way to do this kind of thing. I feel like it doesn't help with readability. Is there a better way? Maybe i missed something in the std library. > > import std.stdio; > Change this: > template FNDR(T){ To this: template isIn(T) { > bool isIn(T Element, T[] Array){ > bool rtn=false; > foreach(T ArrayElement; Array){ > if(Element==ArrayElement){ > rtn=true; > } > } > return rtn; > } > } > > void main(string[] args) > { > int[3] stuff=[0,1,2]; > if (FNDR!int.isIn(2,stuff)) now: if(isIn(2, stuff)) see implicit function template instantiation (IFTI) in docs. Also, using UFCS (Unified Function Call Syntax (I think)), we can do: if(2.isIn(stuff)) Or if you swap the parameters, and perhaps rename your template/function: if(stuff.contains(2)) > { > writeln("Hello World!"); > } > } -Steve |
April 23, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Hi,everyone, This code must add the 'break', import std.stdio; int x=0; template isin(T){ bool isin(T[] Array,T Element){ bool rtn=false; foreach(T ArrayElement; Array){ if(Element==ArrayElement){ rtn=true; break; ← //here add break } x++; } return rtn; } } void main(string[] args) { int[] stuff=[0,1,2,3,4,5,6,7,8,9,10]; ← //here declare int[] if (stuff.isin(2)) // Much clean! { writeln(x); writeln("Hello World!"); } } ----------------end--------------- Frank |
April 23, 2014 Re: Best way to check for an element in an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to FrankLike | Hi,everyone, It works maybe the best: import std.stdio; template isin(T){ bool isin(T[] Array,T Element){ foreach(T ArrayElement; Array){ if(Element==ArrayElement){ return true;} } return false; } } void main(string[] args) { int[] stuff=[0,1,2,3,4,5,6,7,8,9,10]; if (stuff.isin(2)) { writeln("Hello World!"); } string[] strs =["Hello","world","hi","Everyone"]; if(strs.isin("Hi")) { writeln("find Hi"); } else { writeln("not find Hi from: "~strs); } } ----------------end--------------- Frank |
Copyright © 1999-2021 by the D Language Foundation