Manipulate slice or specific element of range and return range

Ali Çehreli acehreli at yahoo.com
Wed Mar 21 12:53:56 UTC 2018


On 03/21/2018 04:30 AM, Timoses wrote:
> Hey,
> 
> I'm struggling to find a way to achieve this. I've looked through 
> std.algorithm but didn't find anything.. Maybe I'm blind.
> 
> What I would like to do is filter out all spaces in a string and change 
> the front letter to lower case:
> 
>      string m = "My Capital String";
>      string lower = m
>          .filter!(c => c != ' ')
>          .<executeAt>!(0, c => c.toLower) // executeAt does not exist
>          .array.to!string;
>      assert(lower == "myCapitalString");
> 
> or sth like
> 
>      m.filter!(...)
>          .map!((element, int index) {
>              if (index == 0)
>                  return element.toLower;
>              else
>                  break; // stop since we are done manipulating range
>          });
> 
> Anyway to do this?

Here is another one that uses ForwardRange.

import std.range; // empty, take, save, chain, popFrontN;
import std.uni; // asLowerCase;
import std.algorithm; // equal, filter;
import std.conv; // text;

auto initialLowerCased(R)(R str, size_t N = 1) {
     if (str.empty) {
         N = 0;
     }
     auto frontPart = str.take(N);
     auto rest = str.save;
     rest.popFrontN(N);

     return chain(frontPart.asLowerCase, rest);
}

unittest {
     assert(initialLowerCased("My Test String", 4).equal("my test String"));
     assert(initialLowerCased("").equal(""));
}

auto foo(R)(R str) {
     return str.filter!(c => c != ' ').initialLowerCased;
}

void main() {
     auto result = foo("My Capital String");
     // result above is a range. std.conv.text can make a string:
     string lower = result.text;
     assert(lower == "myCapitalString");
}

Ali


More information about the Digitalmars-d-learn mailing list