std.algorithm.find and array of needles?

John Colvin john.loughran.colvin at gmail.com
Mon Mar 3 14:19:15 PST 2014


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));
}


More information about the Digitalmars-d-learn mailing list