www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.algorithm.find and array of needles?

reply captaindet <2krnk gmx.net> writes:
std.algorithm.find has an overload that works with several needles:

// phobos doc example:
int[] a = [ 1, 4, 2, 3 ];
assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

the function i want to write has to deal with variadic arguments serving as
needles. unfortunately, i failed trying to make find work with the needles
provided in an array:

int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
int[][] ns = [  [ 7, 6 ], [ 4, 3 ] ];
auto res = find( a, ns );
//Error: template std.algorithm.find does not match any function template
declaration. Candidates are:

any ideas how this can be achieved?

thanks
/det
Mar 03 2014
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
 std.algorithm.find has an overload that works with several 
 needles:

 // phobos doc example:
 int[] a = [ 1, 4, 2, 3 ];
 assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

 the function i want to write has to deal with variadic 
 arguments serving as needles. unfortunately, i failed trying to 
 make find work with the needles provided in an array:

 int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
 int[][] ns = [  [ 7, 6 ], [ 4, 3 ] ];
 auto res = find( a, ns );
 //Error: template std.algorithm.find does not match any 
 function template declaration. Candidates are:

 any ideas how this can be achieved?

 thanks
 /det
You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));
Mar 03 2014
parent reply captaindet <2krnk gmx.net> writes:
On 2014-03-03 14:58, John Colvin wrote:
 On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
 std.algorithm.find has an overload that works with several needles:

 // phobos doc example:
 int[] a = [ 1, 4, 2, 3 ];
 assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

 the function i want to write has to deal with variadic arguments serving as
needles. unfortunately, i failed trying to make find work with the needles
provided in an array:

 int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
 int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
 auto res = find( a, ns );
 //Error: template std.algorithm.find does not match any function template
declaration. Candidates are:

 any ideas how this can be achieved?

 thanks
 /det
You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));
thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det
Mar 03 2014
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote:
 On 2014-03-03 14:58, John Colvin wrote:
 On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
 std.algorithm.find has an overload that works with several 
 needles:

 // phobos doc example:
 int[] a = [ 1, 4, 2, 3 ];
 assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

 the function i want to write has to deal with variadic 
 arguments serving as needles. unfortunately, i failed trying 
 to make find work with the needles provided in an array:

 int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
 int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
 auto res = find( a, ns );
 //Error: template std.algorithm.find does not match any 
 function template declaration. Candidates are:

 any ideas how this can be achieved?

 thanks
 /det
You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));
thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det
Luckily, you don't have to. foreach over tuples is awesome: import std.typecons; import std.algorithm; auto makeProperNeedle(T)(T needle) { //do something to needle return needle; } auto foo(A, T ...)(A[] a, T preNeedles) { Tuple!T needles; foreach(i, preNeedle; preNeedles) { needles[i] = makeProperNeedle(preNeedle); } //use find as follows. For example: return a.find(needles.expand); } unittest { assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3)); }
Mar 03 2014
parent captaindet <2krnk gmx.net> writes:
On 2014-03-03 16:19, John Colvin wrote:
 On Monday, 3 March 2014 at 22:03:24 UTC, captaindet wrote:
 On 2014-03-03 14:58, John Colvin wrote:
 On Monday, 3 March 2014 at 19:35:53 UTC, captaindet wrote:
 std.algorithm.find has an overload that works with several needles:

 // phobos doc example:
 int[] a = [ 1, 4, 2, 3 ];
 assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));

 the function i want to write has to deal with variadic arguments serving as
needles. unfortunately, i failed trying to make find work with the needles
provided in an array:

 int[] a = [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ];
 int[][] ns = [ [ 7, 6 ], [ 4, 3 ] ];
 auto res = find( a, ns );
 //Error: template std.algorithm.find does not match any function template
declaration. Candidates are:

 any ideas how this can be achieved?

 thanks
 /det
You can use a variadic template function instead of variadic slice construction: void foo(A, T ...)(A[] a, T ns) { //use find as follows. For example: return a.find(ns); } assert(foo([1,2,3,4], 3, 6, 2) == Tuple!([2,3,4], 2));
thanks, john. i was afraid that this is the hoop i might have to jump through ;) which is fine for the simple case i asked for. in another case, i would need to construct a needle proper from each pre-needle that is one the variadic arguments. this seems impossible now. so i probably have to make the pre-needles template parameters and enter the dreadful realm of std.typetuple... guess staticMap is my friend here. cheers /det
Luckily, you don't have to. foreach over tuples is awesome: import std.typecons; import std.algorithm; auto makeProperNeedle(T)(T needle) { //do something to needle return needle; } auto foo(A, T ...)(A[] a, T preNeedles) { Tuple!T needles; foreach(i, preNeedle; preNeedles) { needles[i] = makeProperNeedle(preNeedle); } //use find as follows. For example: return a.find(needles.expand); } unittest { assert(foo([1,2,3,4], 3, 6, 2) == tuple([2,3,4], 3)); }
awesome indeed - works like a charm! many thanks /det
Mar 03 2014