Jump to page: 1 2
Thread overview
Find a char among string (string.findAmong.char)
Jul 05, 2021
BoQsc
Jul 05, 2021
jfondren
Jul 05, 2021
jfondren
Jul 05, 2021
BoQsc
Jul 05, 2021
jfondren
Jul 05, 2021
BoQsc
Jul 05, 2021
jfondren
Jul 06, 2021
BoQsc
Jul 06, 2021
Mike Parker
Jul 06, 2021
rassoc
Jul 06, 2021
BoQsc
Jul 07, 2021
BoQsc
Jul 07, 2021
rassoc
July 05, 2021

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

}

July 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.

>

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

}

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.

July 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:

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));
}
July 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 you replace the findAmong call with [letter].findAmong(alphabet), this works.

Consider:

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

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/YWmaXU

July 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/YWmaXU

It 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
July 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:

>

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/YWmaXU

It 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

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.

July 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.

July 06, 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:

>

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.

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/2Fvenf

July 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/2Fvenf

Looks 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:

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.

July 06, 2021

You can also do:

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
}
« First   ‹ Prev
1 2