Best approach to handle accented letters

Chris via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Oct 28 08:08:59 PDT 2016


On Friday, 28 October 2016 at 14:31:47 UTC, Chris wrote:
> On Friday, 28 October 2016 at 13:50:24 UTC, Alfred Newman wrote:
>
> It boils down to something like:
>
> if (c in _accent)
>   return _accent[c];
> else
>   return c;
>
> Just a normal lambda (condition true) ? yes : no;
>
> I'd recommend you to use Marc's approach, though.

What you basically do is you pass the logic on to `map` and `map` 
applies it to each item in the range (cf. [1]):

map!(myLogic)(range);

or (more idiomatic)

range.map!(myLogic);

This is true of a lot of functions, or rather templates, in the 
Phobos standard library, especially functions in std.algorithm 
(like find [2], canFind, filter etc.). In this way, instead of 
writing for-loops with if-else statements, you pass the logic to 
be applied within the `!()`-part of the template.

// Filter the letter 'l'
auto result = "Hello, world!".filter!(a => a != 'l'); // returns 
"Heo, word!"

However, what is returned is not a string. So this won't work:

`writeln("Result is " ~ result);`

// Error: incompatible types for (("Result is ") ~ (result)): 
'string' and
// 'FilterResult!(__lambda2, string)'

It returns a `FilterResult`.

To fix this, you can either write:
`
import std.conv;
auto result = "Hello, world!".filter!(a => a != 'l').to!string;
`
which converts it into a string.

or you do this:

`
import std.array;
auto result = "Hello, world!".filter!(a => a != 'l').array;
`

Then you have a string again and

`
writeln("Result is " ~ result);
`
works.

Just bear that in mind, because you will get the above error 
sometimes. Marc's example is idiomatic D and you should become 
familiar with it asap.

void main()
{
     auto str = "très élégant";
     immutable accents = unicode.Diacritic;
     auto removed = str
         // normalize each character
         .normalize!NFD
         // replace each diacritic with its non-diacritic 
counterpart
         .filter!(c => !accents[c])
         // convert each item in FilterResult back to string.
         .to!string;
     writeln(removed);  // prints "tres elegant"
}

[1] http://dlang.org/phobos/std_algorithm_iteration.html#.map
[1] http://dlang.org/phobos/std_algorithm_searching.html#.find


More information about the Digitalmars-d-learn mailing list