Re: Best way to check for an element in an array?
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
Re: Best way to check for an element in an array?
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
Re: Best way to check for an element in an array?
On Mon, 21 Apr 2014 23:25:39 -0400, Taylor Hillegeist taylorh...@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
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?
Re: Best way to check for an element in an array?
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?
Re: Best way to check for an element in an array?
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?
Re: Best way to check for an element in an array?
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