www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.algorithm.canFind behavior difference between arrays and elements

reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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

```


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?
Dec 07 2018
next sibling parent reply Dennis <dkorpel gmail.com> writes:
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"));
Dec 07 2018
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Dec 07 2018
prev sibling parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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.
Dec 07 2018
parent Arun Chandrasekaran <aruncxy gmail.com> writes:
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!
Dec 07 2018
prev sibling parent reply Seb <seb wilzba.ch> writes:
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

 ```


 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
Dec 07 2018
next sibling parent Arun Chandrasekaran <aruncxy gmail.com> writes:
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

 ```


 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!
Dec 07 2018
prev sibling parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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

 ```


 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.
Dec 07 2018
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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

 ```


 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
Dec 07 2018
prev sibling parent reply Seb <seb wilzba.ch> writes:
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.
Dec 07 2018
parent Arun Chandrasekaran <aruncxy gmail.com> writes:
On Friday, 7 December 2018 at 20:28:37 UTC, Seb wrote:
 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.
Sure, here it is https://github.com/dlang/phobos/pull/6796
Dec 07 2018