Thread overview
Create a case-insensitive startsWith
Apr 28, 2015
PhilipDaniels
Apr 28, 2015
weaselcat
Apr 28, 2015
Justin Whear
Apr 29, 2015
PhilipDaniels
Apr 30, 2015
Justin Whear
April 28, 2015
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"))
April 28, 2015
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.)
April 28, 2015
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))

April 29, 2015
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...

April 29, 2015
if("0X".std.string.indexOf("0x", CaseSensitive.no) == 0)

should work
April 30, 2015
Note that my solution relies on the pre-release version of std.uni, those lazy functions aren't in the latest release.