digitalmars.D.learn - Find a char among string (string.findAmong.char)
- BoQsc (21/31) Jul 05 2021 This is the code: You can run it at:
- jfondren (10/41) Jul 05 2021 If you replace the findAmong call with
- jfondren (16/18) Jul 05 2021 Consider:
- BoQsc (5/24) Jul 05 2021 If I use `[letter].findAmong(alphabet)` in my code, it considers
- jfondren (12/16) Jul 05 2021 It returns a zero-length array that, because it's not null, is
- BoQsc (30/46) Jul 05 2021 Oh alright I think I fixed it with your guidance.
- jfondren (5/11) Jul 05 2021 I suggest canFind, like in my earlier example. findAmong is like
- BoQsc (6/18) Jul 06 2021 I tried out .canFind method, and to test it I removed the letter
- Mike Parker (13/18) Jul 06 2021 Looks like it has something to do with the alias. Static arrays
- rassoc (14/14) Jul 06 2021 You can also do:
I get an error when I try to find that letter is among alphabet.onlineapp.d(13): Error: template `std.algorithm.searching.findAmong` cannot deduce function from argument types `!()(immutable(char), immutable(string))`, candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694): `findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, ForwardRange choices)` with `pred = "a == b", InputRange = immutable(char), ForwardRange = string` must satisfy the following constraint: ` isInputRange!InputRange`This is the code: You can run it at: https://run.dlang.io/is/5cvuUZ import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (letter.findAmong(alphabet)){ write("found"); } write(letter); } }
Jul 05 2021
On Monday, 5 July 2021 at 18:45:10 UTC, BoQsc wrote:I get an error when I try to find that letter is among alphabet.If you replace the findAmong call with `[letter].findAmong(alphabet)`, this works. Both arguments to findAmong need to be ranges; you're calling it here against an immutable(char). As it says in the error: ``` from argument types `!()(immutable(char), immutable(string))` ``` immutable(char) looks a lot like immutable(char)[], but the latter is a string and the former is just a singular char.onlineapp.d(13): Error: template `std.algorithm.searching.findAmong` cannot deduce function from argument types `!()(immutable(char), immutable(string))`, candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694): `findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, ForwardRange choices)` with `pred = "a == b", InputRange = immutable(char), ForwardRange = string` must satisfy the following constraint: ` isInputRange!InputRange`This is the code: You can run it at: https://run.dlang.io/is/5cvuUZ import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (letter.findAmong(alphabet)){ write("found"); } write(letter); } }
Jul 05 2021
On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote:If you replace the findAmong call with `[letter].findAmong(alphabet)`, this works.Consider: ```d import std; void main() { import std.ascii : alphabet = letters; string wordExample = "Book."; foreach (letter; wordExample) { writefln!"%c is %sa letter"(letter, [letter].findAmong(alphabet).length ? "" : "not "); writefln!"%c is %sa letter"(letter, alphabet.canFind(letter) ? "" : "not "); } writeln("___>>___finally some letters".findAmong(alphabet)); } ```
Jul 05 2021
On Monday, 5 July 2021 at 18:59:09 UTC, jfondren wrote:On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote:If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXUIf you replace the findAmong call with `[letter].findAmong(alphabet)`, this works.Consider: ```d import std; void main() { import std.ascii : alphabet = letters; string wordExample = "Book."; foreach (letter; wordExample) { writefln!"%c is %sa letter"(letter, [letter].findAmong(alphabet).length ? "" : "not "); writefln!"%c is %sa letter"(letter, alphabet.canFind(letter) ? "" : "not "); } writeln("___>>___finally some letters".findAmong(alphabet)); } ```
Jul 05 2021
On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote:If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXUIt returns a zero-length array that, because it's not null, is true. That's why I used .length in my example. ``` $ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] ? true : false)' 0 true $ rdmd --eval 'writeln([].length); writeln([] ? true : false)' 0 false ```
Jul 05 2021
On Monday, 5 July 2021 at 19:25:23 UTC, jfondren wrote:On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote:Oh alright I think I fixed it with your guidance. ``` import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ if (([letter].findAmong(alphabet)).length){ write(letter); write(" letter is found among the alphabet."); writeln; } } } ``` But I really don't like how it looks less readable and makes less sense on first look. `if (([letter].findAmong(alphabet)).length)` I'd like to use some method on the `letter` instead of [] And `.length` does not make a lot of sense when reading like an english sentence.If I use `[letter].findAmong(alphabet)` in my code, it considers a dot (.) punctuation character as a letter. You can see it here: https://run.dlang.io/is/YWmaXUIt returns a zero-length array that, because it's not null, is true. That's why I used .length in my example. ``` $ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] ? true : false)' 0 true $ rdmd --eval 'writeln([].length); writeln([] ? true : false)' 0 false ```
Jul 05 2021
On Monday, 5 July 2021 at 19:34:14 UTC, BoQsc wrote:But I really don't like how it looks less readable and makes less sense on first look. `if (([letter].findAmong(alphabet)).length)` I'd like to use some method on the `letter` instead of [] And `.length` does not make a lot of sense when reading like an english sentence.I suggest canFind, like in my earlier example. findAmong is like "consume this range until you find one of these things, and then return the remainder of the range". It doesn't really fit your use.
Jul 05 2021
On Monday, 5 July 2021 at 19:48:13 UTC, jfondren wrote:On Monday, 5 July 2021 at 19:34:14 UTC, BoQsc wrote:I tried out .canFind method, and to test it I removed the letter 'o' from the Alphabet. Weirdly enough .canFind method still found 'o' letter among the Alphabet. https://run.dlang.io/is/2FvenfBut I really don't like how it looks less readable and makes less sense on first look. `if (([letter].findAmong(alphabet)).length)` I'd like to use some method on the `letter` instead of [] And `.length` does not make a lot of sense when reading like an english sentence.I suggest canFind, like in my earlier example. findAmong is like "consume this range until you find one of these things, and then return the remainder of the range". It doesn't really fit your use.
Jul 06 2021
On Tuesday, 6 July 2021 at 11:35:14 UTC, BoQsc wrote:I tried out .canFind method, and to test it I removed the letter 'o' from the Alphabet. Weirdly enough .canFind method still found 'o' letter among the Alphabet. https://run.dlang.io/is/2FvenfLooks like it has something to do with the alias. Static arrays aren't ranges, so you should really be seeing the same error you would if you passed `letters` directly. Change the `canFind` call to take a slice of the array: ```d if (letters[].canFind(letter)){ ``` And it outputs the following as expected: ``` k letter is found among the alphabet. ``` This warrants a bug report with a minimized example.
Jul 06 2021
You can also do: ```d import std; void main() { // https://dlang.org/phobos/std_ascii.html#.lowercase "Book.".filter!(c => lowercase.canFind(c)) .each!(c => writeln(c, " found")); // Output: // o found // o found // k found } ```
Jul 06 2021
On Tuesday, 6 July 2021 at 15:48:35 UTC, rassoc wrote:You can also do: ```d import std; void main() { // https://dlang.org/phobos/std_ascii.html#.lowercase "Book.".filter!(c => lowercase.canFind(c)) .each!(c => writeln(c, " found")); // Output: // o found // o found // k found } ```I really don't like reading arrow functions. It takes some more effort to understand, follow and get used to them. I'd like something simple and effortless looking and feeling that would make code readable similarly to an english sentence. Such as this, but as noted, this does not work as intended/assumed by me: ``` if (letter.findAmong(alphabet)){ write("found"); } ```
Jul 06 2021
I think nested foreach loops are more readable. ``` import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ foreach (alphabetLetter; letters){ if (letter == alphabetLetter) { writeln(letter); } } } } ```
Jul 07 2021
On Wednesday, 7 July 2021 at 12:22:11 UTC, BoQsc wrote:I think nested foreach loops are more readable. ``` import std; void main() { alias alphabet = letters; char[26] letters = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; string wordExample = "Book."; foreach (letter; wordExample){ foreach (alphabetLetter; letters){ if (letter == alphabetLetter) { writeln(letter); } } } } ```Use whatever fits your style best or what you are most familar with. But be aware that there's a concise alternative: ```d import std; void main() { import std.ascii; // because there's also std.uni.isLower "Book.".filter!isLower.each!writeln; } ``` or alternatively with fully-qualified naming: ```d import std; void main() { "Book.".filter!(std.ascii.isLower).each!writeln; } ```
Jul 07 2021