Thread overview
std.algorithm.find and array of needles?
Mar 03, 2014
captaindet
Mar 03, 2014
John Colvin
Mar 03, 2014
captaindet
Mar 03, 2014
John Colvin
Mar 03, 2014
captaindet
March 03, 2014
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
March 03, 2014
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));
March 03, 2014
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
March 03, 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));
}
March 03, 2014
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