www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - startsWith using an array of needles

reply "Byron" <byron.heads gmail.com> writes:
I am trying to use startsWith with an array of needles.  Failes 
with not being able to match any functions.  Not sure if there is 
a work around.

const auto ignore = [".git/", ".gitignore"];

foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a 
=> !a.name.startsWith(ignore))) {
		writeln(e.name);
	}


-Byron
Aug 20 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, August 20, 2013 17:58:19 Byron wrote:
 I am trying to use startsWith with an array of needles. Failes
 with not being able to match any functions. Not sure if there is
 a work around.
 
 const auto ignore = [".git/", ".gitignore"];
 
 foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a
 => !a.name.startsWith(ignore))) {
 writeln(e.name);
 }
startsWith dosen't take an array of needles. It takes a variadic list of them. So, it needs to be something more like !a.name.startsWith(".git/", ".gitignore") If you want to save the list though, you can use std.typetuple.TypeTuple and an alias: alias TypeTuple!(".git/", ".gitignore") ignore; At that point, the rest of your code should work as-is. - Jonathan M Davis
Aug 20 2013
next sibling parent reply "Byron" <byron.heads gmail.com> writes:
On Tuesday, 20 August 2013 at 16:51:35 UTC, Jonathan M Davis 
wrote:
 On Tuesday, August 20, 2013 17:58:19 Byron wrote:
 I am trying to use startsWith with an array of needles. Failes
 with not being able to match any functions. Not sure if there 
 is
 a work around.
 
 const auto ignore = [".git/", ".gitignore"];
 
 foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a
 => !a.name.startsWith(ignore))) {
 writeln(e.name);
 }
startsWith dosen't take an array of needles. It takes a variadic list of them. So, it needs to be something more like !a.name.startsWith(".git/", ".gitignore") If you want to save the list though, you can use std.typetuple.TypeTuple and an alias: alias TypeTuple!(".git/", ".gitignore") ignore; At that point, the rest of your code should work as-is. - Jonathan M Davis
What if I want to load my ignore list from a file?
Aug 20 2013
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, August 20, 2013 19:14:08 Byron wrote:
 On Tuesday, 20 August 2013 at 16:51:35 UTC, Jonathan M Davis
 
 wrote:
 On Tuesday, August 20, 2013 17:58:19 Byron wrote:
 I am trying to use startsWith with an array of needles. Failes
 with not being able to match any functions. Not sure if there
 is
 a work around.
 
 const auto ignore = [".git/", ".gitignore"];
 
 foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a
 => !a.name.startsWith(ignore))) {
 writeln(e.name);
 }
startsWith dosen't take an array of needles. It takes a variadic list of them. So, it needs to be something more like !a.name.startsWith(".git/", ".gitignore") If you want to save the list though, you can use std.typetuple.TypeTuple and an alias: alias TypeTuple!(".git/", ".gitignore") ignore; At that point, the rest of your code should work as-is. - Jonathan M Davis
What if I want to load my ignore list from a file?
Then you'll have to make separate calls to startsWith. The number of arguments has to be known at compile time, so unless the number of arguments from the file is always the same, and you have a variable per argument, you can't do it. But unless the needles have similar prefixes, there isn't going to be much of an efficiency hit from multiple calls. - Jonathan M Davis
Aug 20 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, August 20, 2013 19:14:08 Byron wrote:
 On Tuesday, 20 August 2013 at 16:51:35 UTC, Jonathan M Davis
 
 wrote:
 On Tuesday, August 20, 2013 17:58:19 Byron wrote:
 I am trying to use startsWith with an array of needles. Failes
 with not being able to match any functions. Not sure if there
 is
 a work around.
 
 const auto ignore = [".git/", ".gitignore"];
 
 foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a
 => !a.name.startsWith(ignore))) {
 writeln(e.name);
 }
startsWith dosen't take an array of needles. It takes a variadic list of them. So, it needs to be something more like !a.name.startsWith(".git/", ".gitignore") If you want to save the list though, you can use std.typetuple.TypeTuple and an alias: alias TypeTuple!(".git/", ".gitignore") ignore; At that point, the rest of your code should work as-is. - Jonathan M Davis
What if I want to load my ignore list from a file?
Then you'll have to make separate calls to startsWith. The number of arguments has to be known at compile time, so unless the number of arguments from the file is always the same, and you have a variable per argument, you can't do it. But unless the needles have similar prefixes, there isn't going to be much of an efficiency hit from multiple calls. - Jonathan M Davis
Aug 20 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Aug 20, 2013 at 03:16:28PM -0400, Jonathan M Davis wrote:
 On Tuesday, August 20, 2013 19:14:08 Byron wrote:
 On Tuesday, 20 August 2013 at 16:51:35 UTC, Jonathan M Davis
 
 wrote:
 On Tuesday, August 20, 2013 17:58:19 Byron wrote:
 I am trying to use startsWith with an array of needles. Failes
 with not being able to match any functions. Not sure if there is
 a work around.
 
 const auto ignore = [".git/", ".gitignore"];
 
 foreach(DirEntry e; getcwd.dirEntries(SpanMode.depth).filter!(a
 => !a.name.startsWith(ignore))) {
 writeln(e.name);
 }
startsWith dosen't take an array of needles. It takes a variadic list of them. So, it needs to be something more like !a.name.startsWith(".git/", ".gitignore") If you want to save the list though, you can use std.typetuple.TypeTuple and an alias: alias TypeTuple!(".git/", ".gitignore") ignore; At that point, the rest of your code should work as-is. - Jonathan M Davis
What if I want to load my ignore list from a file?
Then you'll have to make separate calls to startsWith. The number of arguments has to be known at compile time, so unless the number of arguments from the file is always the same, and you have a variable per argument, you can't do it. But unless the needles have similar prefixes, there isn't going to be much of an efficiency hit from multiple calls.
[...] And if you're worried about efficiency, I suggest constructing and caching a regex for doing the matching. It will be better than a long series of startsWith calls if your ignore list is large. T -- "640K ought to be enough" -- Bill G., 1984. "The Internet is not a primary goal for PC usage" -- Bill G., 1995. "Linux has no impact on Microsoft's strategy" -- Bill G., 1999.
Aug 20 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 startsWith dosen't take an array of needles. It takes a 
 variadic list of them.
All the argument after the first of startsWith could be required to be of the same type, for this D offers: void foo(T)(T[] items...) {} void main() { foo(1); foo(1, 2); foo(1, 2, 3); foo([1]); foo([1, 2]); foo([1, 2, 3]); } Isn't it better to modify startsWith a little like this? Bye, bearophile
Aug 20 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, August 20, 2013 19:32:57 bearophile wrote:
 Jonathan M Davis:
 startsWith dosen't take an array of needles. It takes a
 variadic list of them.
All the argument after the first of startsWith could be required to be of the same type, for this D offers: void foo(T)(T[] items...) {} void main() { foo(1); foo(1, 2); foo(1, 2, 3); foo([1]); foo([1, 2]); foo([1, 2, 3]); } Isn't it better to modify startsWith a little like this?
Things get messy when you try and do stuff like that thanks to being able to have arrays of arrays and whatnot. We already have issues with several functions where you're forced to give them strings instead of characters. Type-safe variadics are particularly bad thanks to the fact that they acccept both indivdual elements and an array. Also, allowing what you suggest would increase the risk of bugs when you meant to do something like search for a string in an array of strings but accidentally give it a string to search in. Right now, stuff like that gets caught. - Jonathan M Davis
Aug 20 2013