www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Create a case-insensitive startsWith

reply "PhilipDaniels" <phil foo.com> writes:
Beginner question. Given

   if (startsWith(input, "0x", "0X"))

How do I turn that into a case-insensitive startsWith? startsWith 
says it takes a predicate but I can't figure out how to pass it 
one. The examples all use "a == b" !? These attempts below, and 
other things I have tried, fail with "cannot deduce function from 
argument types".

   if (startsWith!"icmp(a, b) == 0"(input, "0x"))
   if (startsWith!"std.uni.icmp(a, b) == 0"(input, "0x"))
   if (startsWith!((a,b) => icmp(a,b) == 0)(input, "0x"))
Apr 28 2015
next sibling parent "weaselcat" <weaselcat gmail.com> writes:
On Tuesday, 28 April 2015 at 21:45:10 UTC, PhilipDaniels wrote:
 Beginner question. Given

   if (startsWith(input, "0x", "0X"))

 How do I turn that into a case-insensitive startsWith? 
 startsWith says it takes a predicate but I can't figure out how 
 to pass it one. The examples all use "a == b" !? These attempts 
 below, and other things I have tried, fail with "cannot deduce 
 function from argument types".

   if (startsWith!"icmp(a, b) == 0"(input, "0x"))
   if (startsWith!"std.uni.icmp(a, b) == 0"(input, "0x"))
   if (startsWith!((a,b) => icmp(a,b) == 0)(input, "0x"))
I believe the issue is that the predicate expects a boolean, icmp returns an int. Try a == toLower(b) as your predicate(there's probably a better solution somewhere hidden in phobos though.)
Apr 28 2015
prev sibling next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
On Tue, 28 Apr 2015 21:45:07 +0000, PhilipDaniels wrote:

 Beginner question. Given
 
    if (startsWith(input, "0x", "0X"))
 
 How do I turn that into a case-insensitive startsWith? startsWith says
 it takes a predicate but I can't figure out how to pass it one. The
 examples all use "a == b" !? These attempts below, and other things I
 have tried, fail with "cannot deduce function from argument types".
 
    if (startsWith!"icmp(a, b) == 0"(input, "0x"))
    if (startsWith!"std.uni.icmp(a, b) == 0"(input, "0x"))
    if (startsWith!((a,b) => icmp(a,b) == 0)(input, "0x"))
The issue is that those icmp functions take strings as arguments while startsWith expects the predicate to take individual characters. I believe the best solution here is to use the lazy toLowerCase function in std.uni and the default predicate: if (startsWith(input.toLowerCase, "0x".toLowerCase))
Apr 28 2015
parent reply "PhilipDaniels" <phil foo.com> writes:
On Tuesday, 28 April 2015 at 22:34:07 UTC, Justin Whear wrote:
    if (startsWith!"icmp(a, b) == 0"(input, "0x"))
    if (startsWith!"std.uni.icmp(a, b) == 0"(input, "0x"))
    if (startsWith!((a,b) => icmp(a,b) == 0)(input, "0x"))
The issue is that those icmp functions take strings as arguments while startsWith expects the predicate to take individual characters.
Thanks. That seems obvious now that you mention it but honestly I could not tell that from the documentation :-(
 I believe the best solution here is to use the lazy toLowerCase 
 function
 in std.uni and the default predicate:
   if (startsWith(input.toLowerCase, "0x".toLowerCase))
I think I will have to make a "string idioms" wiki page...
Apr 29 2015
parent Justin Whear <justin economicmodeling.com> writes:
Note that my solution relies on the pre-release version of std.uni, those 
lazy functions aren't in the latest release.
Apr 30 2015
prev sibling parent "Robert burner Schadek" <rburners gmail.com> writes:
if("0X".std.string.indexOf("0x", CaseSensitive.no) == 0)

should work
Apr 29 2015