Jump to page: 1 2
Thread overview
std.algorithm.canFind behavior difference between arrays and elements
Dec 07, 2018
Dennis
Dec 07, 2018
Seb
Dec 07, 2018
Seb
December 07, 2018
I'm trying to find the needle in the hay that's an array of strings. So the second assert fails for some reason. Is this expected? https://run.dlang.io/is/7OrZTA

```
#!/usr/bin/rdmd

void main()
{
    import std.experimental.all;
    string s1 = "aaa111aaa";
    string s2 = "aaa222aaa";
    string s3 = "aaa333aaa";
    string s4 = "aaa444aaa";
    const hay = [s1, s2, s3, s4];
    assert(canFind(s1, "111"));
    assert(canFind(hay, "111"));
}
```

Why is there a difference in the behavior?
December 07, 2018
On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
> Why is there a difference in the behavior?

Your first assert expression is looking for a string in a larger string, your second expression looks for hay which is not a string but a string[]. To flatten the array, use:

assert(canFind(hay.join, "111"));
December 07, 2018
On 12/7/18 1:57 PM, Dennis wrote:
> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>> Why is there a difference in the behavior?
> 
> Your first assert expression is looking for a string in a larger string, your second expression looks for hay which is not a string but a string[]. To flatten the array, use:
> 
> assert(canFind(hay.join, "111"));

1. Use joiner, not join, as this creates a temporary array and immediately throws it away (wasteful)
2. It's not exactly as simple as that, because it will find "111" that spans 2 elements (unless that's what you want).

You'd probably want to use some kind of delimiter, like:

assert(canFind(hay.joiner("\0"), "111"));

-Steve
December 07, 2018
On Friday, 7 December 2018 at 18:57:48 UTC, Dennis wrote:
> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>> Why is there a difference in the behavior?
>
> Your first assert expression is looking for a string in a larger string, your second expression looks for hay which is not a string but a string[]. To flatten the array, use:
>
> assert(canFind(hay.join, "111"));

This succeeds.

assert(canFind(hay, "aaa222aaa"));

So the difference in the behaviour is caused by canFind checking for equality when string[] is passed. Is this the expected behaviour? I wouldn't want to join the array, for the array could be really big.
December 07, 2018
On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
> I'm trying to find the needle in the hay that's an array of strings. So the second assert fails for some reason. Is this expected? https://run.dlang.io/is/7OrZTA
>
> ```
> #!/usr/bin/rdmd
>
> void main()
> {
>     import std.experimental.all;
>     string s1 = "aaa111aaa";
>     string s2 = "aaa222aaa";
>     string s3 = "aaa333aaa";
>     string s4 = "aaa444aaa";
>     const hay = [s1, s2, s3, s4];
>     assert(canFind(s1, "111"));
>     assert(canFind(hay, "111"));
> }
> ```
>
> Why is there a difference in the behavior?

Alternatively to the answers above you can also use a custom lambda for canFind:

https://run.dlang.io/is/QOXYbe
December 07, 2018
On Friday, 7 December 2018 at 19:08:05 UTC, Arun Chandrasekaran wrote:
> On Friday, 7 December 2018 at 18:57:48 UTC, Dennis wrote:
>> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>>> Why is there a difference in the behavior?
>>
>> Your first assert expression is looking for a string in a larger string, your second expression looks for hay which is not a string but a string[]. To flatten the array, use:
>>
>> assert(canFind(hay.join, "111"));
>
> This succeeds.
>
> assert(canFind(hay, "aaa222aaa"));
>
> So the difference in the behaviour is caused by canFind checking for equality when string[] is passed. Is this the expected behaviour? I wouldn't want to join the array, for the array could be really big.

Actually, canFind documentation is perfect. https://dlang.org/phobos/std_algorithm_searching.html#.canFind

assert( canFind!((string a, string b) => a.startsWith(b))(words, "bees"));

Thanks for the help anyways!
December 07, 2018
On Friday, 7 December 2018 at 19:12:31 UTC, Seb wrote:
> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>> I'm trying to find the needle in the hay that's an array of strings. So the second assert fails for some reason. Is this expected? https://run.dlang.io/is/7OrZTA
>>
>> ```
>> #!/usr/bin/rdmd
>>
>> void main()
>> {
>>     import std.experimental.all;
>>     string s1 = "aaa111aaa";
>>     string s2 = "aaa222aaa";
>>     string s3 = "aaa333aaa";
>>     string s4 = "aaa444aaa";
>>     const hay = [s1, s2, s3, s4];
>>     assert(canFind(s1, "111"));
>>     assert(canFind(hay, "111"));
>> }
>> ```
>>
>> Why is there a difference in the behavior?
>
> Alternatively to the answers above you can also use a custom lambda for canFind:
>
> https://run.dlang.io/is/QOXYbe

That's elegant!
December 07, 2018
On Friday, 7 December 2018 at 19:12:31 UTC, Seb wrote:
> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>> I'm trying to find the needle in the hay that's an array of strings. So the second assert fails for some reason. Is this expected? https://run.dlang.io/is/7OrZTA
>>
>> ```
>> #!/usr/bin/rdmd
>>
>> void main()
>> {
>>     import std.experimental.all;
>>     string s1 = "aaa111aaa";
>>     string s2 = "aaa222aaa";
>>     string s3 = "aaa333aaa";
>>     string s4 = "aaa444aaa";
>>     const hay = [s1, s2, s3, s4];
>>     assert(canFind(s1, "111"));
>>     assert(canFind(hay, "111"));
>> }
>> ```
>>
>> Why is there a difference in the behavior?
>
> Alternatively to the answers above you can also use a custom lambda for canFind:
>
> https://run.dlang.io/is/QOXYbe

Just curious, how do we find multiple needles? This throws compilation error

    assert(hay.canFind!(e => (e.canFind(["111", "222"]))));

An example in the doc would be helpful.

December 07, 2018
On 12/7/18 2:38 PM, Arun Chandrasekaran wrote:
> On Friday, 7 December 2018 at 19:12:31 UTC, Seb wrote:
>> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>>> I'm trying to find the needle in the hay that's an array of strings. So the second assert fails for some reason. Is this expected? https://run.dlang.io/is/7OrZTA
>>>
>>> ```
>>> #!/usr/bin/rdmd
>>>
>>> void main()
>>> {
>>>     import std.experimental.all;
>>>     string s1 = "aaa111aaa";
>>>     string s2 = "aaa222aaa";
>>>     string s3 = "aaa333aaa";
>>>     string s4 = "aaa444aaa";
>>>     const hay = [s1, s2, s3, s4];
>>>     assert(canFind(s1, "111"));
>>>     assert(canFind(hay, "111"));
>>> }
>>> ```
>>>
>>> Why is there a difference in the behavior?
>>
>> Alternatively to the answers above you can also use a custom lambda for canFind:
>>
>> https://run.dlang.io/is/QOXYbe
> 
> Just curious, how do we find multiple needles? This throws compilation error
> 
>      assert(hay.canFind!(e => (e.canFind(["111", "222"]))));

Almost, you have extra braces:

       assert(hay.canFind!(e => (e.canFind( "111", "222" ))));

In other words, when searching for extra needles, each needle is a new parameter to find/canFind.

-Steve
December 07, 2018
On Friday, 7 December 2018 at 19:38:29 UTC, Arun Chandrasekaran wrote:
> On Friday, 7 December 2018 at 19:12:31 UTC, Seb wrote:
>> On Friday, 7 December 2018 at 18:51:27 UTC, Arun Chandrasekaran wrote:
>>> [...]
>>
>> Alternatively to the answers above you can also use a custom lambda for canFind:
>>
>> https://run.dlang.io/is/QOXYbe
>
> Just curious, how do we find multiple needles? This throws compilation error
>
>     assert(hay.canFind!(e => (e.canFind(["111", "222"]))));
>
> An example in the doc would be helpful.


It's variadic: https://run.dlang.io/is/AKkKA9

Please feel free to add an example to the docs.
« First   ‹ Prev
1 2