www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - endsWith - for a string vs an array of strings

reply "Laeeth Isharc" <laeethnospam spammenot_laeeth.com> writes:
I understand from previous discussion there is some difficulty 
over immutability.  I did not quite figure out what the solution 
was in this case:

import std.array;
import std.string;
import std.stdio;
void main(string[] args)
{
	string[] test=["1","two","three!"];
	auto a="arghtwo".endsWith(test);
	writefln("%s",a);
}

This does not compile...

test.d(7): Error: template std.algorithm.endsWith cannot deduce 
function from argument types !()(string, string[]), candidates 
are:
/usr/include/dmd/phobos/std/algorithm.d(6143):        
std.algorithm.endsWith(alias pred = "a == b", Range, 
Needles...)(Range doesThisEnd, Needles withOneOfThese) if 
(isBidirectionalRange!Range && Needles.length > 1 && 
is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[0])) : bool) 
&& is(typeof(.endsWith!pred(doesThisEnd, 
withOneOfThese[1..__dollar])) : uint))
/usr/include/dmd/phobos/std/algorithm.d(6210):        
std.algorithm.endsWith(alias pred = "a == b", R1, R2)(R1 
doesThisEnd, R2 withThis) if (isBidirectionalRange!R1 && 
isBidirectionalRange!R2 && 
is(typeof(binaryFun!pred(doesThisEnd.back, withThis.back)) : 
bool))
/usr/include/dmd/phobos/std/algorithm.d(6237):        
std.algorithm.endsWith(alias pred = "a == b", R, E)(R 
doesThisEnd, E withThis) if (isBidirectionalRange!R && 
is(typeof(binaryFun!pred(doesThisEnd.back, withThis)) : bool))


Thanks.


Laeeth.
Jan 10 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Laeeth Isharc:

 I understand from previous discussion there is some difficulty 
 over immutability.  I did not quite figure out what the 
 solution was in this case:

 import std.array;
 import std.string;
 import std.stdio;
 void main(string[] args)
 {
 	string[] test=["1","two","three!"];
 	auto a="arghtwo".endsWith(test);
 	writefln("%s",a);
 }
 This does not compile...
Take a look at your error messages:
 std.algorithm.endsWith(alias pred = "a == b", Range, 
 Needles...)(Range doesThisEnd, Needles withOneOfThese)
Needles is not an array type, it's a type tuple, so withOneOfThese doesn't accept an array of strings. This is correct: auto a = "arghtwo".endsWith("1","two","three!"); In D there is a feature that allows a function to accept both an array of items and items, but it's not used here by endsWith, for reasons I don't understand (other people can answer this). So if you really want to pack the strings in some kind of unity, you can do this as workaround: void main() { import std.stdio, std.array, std.string, std.typetuple; alias test = TypeTuple!("1", "two", "three!"); auto b = "arghtwo".endsWith(test[]); b.writeln; } Bye, bearophile
Jan 10 2015
next sibling parent FG <home fgda.pl> writes:
On 2015-01-10 at 21:58, bearophile wrote:
 Needles is not an array type, it's a type tuple, so withOneOfThese doesn't
accept an array of strings. [...]
 So if you really want to pack the strings in some kind of unity, you can do
this as workaround: [...]
I would suggest create a function that does the same thing as endsWith(Range, Needles...) but instead of Needles expanded as a list of arguments it takes in a range of them. In fact I was surprised that there was no such function in std.algorithm present. Therefore I have written endsWithAny for this purpose a moment ago. Is it any good? Please correct if necessary. import std.array; import std.string; import std.stdio; import std.range; uint endsWithAny(alias pred = "a == b", Range, Needles)(Range haystack, Needles needles) if (isBidirectionalRange!Range && isInputRange!Needles && is(typeof(.endsWith!pred(haystack, needles.front)) : bool)) { foreach (i, e; needles) if (endsWith!pred(haystack, e)) return i + 1; return 0; } void main(string[] args) { string[] test = ["1", "two", "three!"]; auto a = "arghtwo".endsWithAny(test); writefln("%s", a); } unittest { string[] hs = ["no-one", "thee", "there were three", "two"]; string[] tab = ["one", "two", "three"]; assert(endsWithAny(hs[0], tab) == 1); assert(endsWithAny(hs[1], tab) == 0); assert(endsWithAny(hs[2], tab) == 3); assert(endsWithAny(hs[3], tab) == 2); }
Jan 10 2015
prev sibling parent reply "Laeeth Isharc" <laeethnospam nospamlaeeth.com> writes:
 Take a look at your error messages:

 std.algorithm.endsWith(alias pred = "a == b", Range, 
 Needles...)(Range doesThisEnd, Needles withOneOfThese)
Needles is not an array type, it's a type tuple, so withOneOfThese doesn't accept an array of strings.
ahhh.. thank you so much for this.
 In D there is a feature that allows a function to accept both 
 an array of items and items, but it's not used here by 
 endsWith, for reasons I don't understand (other people can 
 answer this).
yes - it is funny there is not an overloading that accepts arrays given I suppose this will be quite a common use case. and it's another one of those things far from obvious to a new learner - actually a two stage problem: knowing what the right thing to do is not obvious, and neither is it obvious how to correct your mistake when your first attempt fails. we should cover this in any informal D overview of string-related library functions, on a section for text processing, and for those coming to D from other languages. I very much appreciate your help. Laeeth.
Jan 10 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Laeeth Isharc:

 In D there is a feature that allows a function to accept both 
 an array of items and items,
 yes - it is funny there is not an overloading that accepts 
 arrays
I meant this D feature: void foo(T)(T[] items...) { import std.stdio; items.writeln; } void main() { foo("red", "green", "blue"); foo(["red", "green", "blue"]); auto a = ["red", "green", "blue"]; foo(a); } Bye, bearophile
Jan 10 2015
parent reply "Mengu" <mengukagan gmail.com> writes:
On Saturday, 10 January 2015 at 23:32:47 UTC, bearophile wrote:
 Laeeth Isharc:

 In D there is a feature that allows a function to accept both 
 an array of items and items,
 yes - it is funny there is not an overloading that accepts 
 arrays
I meant this D feature: void foo(T)(T[] items...) { import std.stdio; items.writeln; } void main() { foo("red", "green", "blue"); foo(["red", "green", "blue"]); auto a = ["red", "green", "blue"]; foo(a); } Bye, bearophile
for the curious, expanding tuples and typetuples on ali's book is explained at http://ddili.org/ders/d.en/tuples.html#ix_tuples..expand and at http://ddili.org/ders/d.en/tuples.html#ix_tuples.TypeTuple, std.typetuple.
Jan 11 2015
parent "Laeeth Isharc" <laeethnospam spammenot_laeeth.com> writes:
Thanks for the help to everyone.  It seems a common thing to want 
to check an array as one may not know the variables at compile 
time.  Not that it's more than a few lines to do in D.  But in 
terms of language adoption, small frictions can have large 
consequences over time.  (Modern people don't have much patience 
or sticking power even if viewed rationally the ROI makes these 
things trivial.  That's also because in a corporate environment 
management are not always patient when somebody tries something 
new and not yet mainstream).  Making the standard library easy 
with no sharp edges might have a high payoff over time.

How would one add this note about needing to pass a tuple not an 
array to the docs or wiki ?  For docs, clone and submit a pull 
request?  How about wiki?

On Monday, 12 January 2015 at 07:49:16 UTC, Mengu wrote:
 On Saturday, 10 January 2015 at 23:32:47 UTC, bearophile wrote:
 Laeeth Isharc:

 In D there is a feature that allows a function to accept 
 both an array of items and items,
 yes - it is funny there is not an overloading that accepts 
 arrays
I meant this D feature: void foo(T)(T[] items...) { import std.stdio; items.writeln; } void main() { foo("red", "green", "blue"); foo(["red", "green", "blue"]); auto a = ["red", "green", "blue"]; foo(a); } Bye, bearophile
for the curious, expanding tuples and typetuples on ali's book is explained at http://ddili.org/ders/d.en/tuples.html#ix_tuples..expand and at http://ddili.org/ders/d.en/tuples.html#ix_tuples.TypeTuple, std.typetuple.
Jan 12 2015