www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem with std.algorithm.iteration::substitute

reply Martin Brezl <martin.brzenska googlemail.com> writes:
Hi,

i have a function like this:
```
import std.algorithm.iteration : substitute;
//...
string replace(string content, string[] searches , string 
replace) {
	
	if(searches.empty) return content;

	auto result = content.substitute(searches.front,replace);
	for(size_t i=1; i < searches.length; i++) {
		searches.popFront();
		result = result.substitute(searches.front,replace);
	}
         //...
         return "example return";
}
```
I do not understand why this is not valid. This is the 
compilation Error:
```
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/i
eration.d(5954,48): Error: template std.algorithm.searching.find cannot deduce
function from argument types !(__lambda196)(Result, string), candidates are:
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/s
arching.d(1557,12):        find(alias pred = "a == b", InputRange,
Element)(InputRange haystack, scope Element needle)
   with pred = __lambda196,
        InputRange = Result,
        Element = string
   must satisfy the following constraint:
        is(typeof(binaryFun!pred(haystack.front, needle)) : bool)
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/s
arching.d(1823,12):        find(alias pred, InputRange)(InputRange haystack)
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/
earching.d(1877,4):        find(alias pred = "a == b", R1, R2)(R1 haystack,
scope R2 needle)
   with pred = __lambda196,
        R1 = Result,
        R2 = string
   must satisfy the following constraint:
        isForwardRange!R1
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/s
arching.d(2329,23):        find(alias pred = "a == b", Range, Ranges...)(Range
haystack, Ranges needles)
   with pred = __lambda196,
        Range = Result,
        Ranges = (string)
   must satisfy the following constraint:
        Ranges.length > 1
/home/mab/dlang/dmd-2.089.1/linux/bin64/../../src/phobos/std/algorithm/s
arching.d(2444,19):        find(RandomAccessRange, alias pred,
InputRange)(RandomAccessRange haystack, scope BoyerMooreFinder!(pred,
InputRange) needle)
source/app.d(44,29): Error: template instance 
std.algorithm.iteration.substitute!((a, b) => a == b, Result, 
string, string) error instantiating
source/app.d(44,29): Error: cannot implicitly convert expression 
substitute(result, front(searches), replace) of type 
std.algorithm.iteration.joiner!(MapResult!(__lambda7, 
SubstituteSplitter)).joiner.Result to 
std.algorithm.iteration.joiner!(MapResult!(__lambda7, 
SubstituteSplitter)).joiner.Result
/home/mab/dlang/dmd-2.089.1/linux/bin64/dmd failed with exit code 
1.
```

Can someone explain what is going on? Specially this part: 
"Error: cannot implicitly convert expression substitute(result, 
front(searches), replace) of type 
std.algorithm.iteration.joiner!(MapResult!(__lambda7, 
SubstituteSplitter)).joiner.Result to 
std.algorithm.iteration.joiner!(MapResult!(__lambda7, 
SubstituteSplitter)).joiner.Result"

In the Example "Multiple substitutes" in 
https://dlang.org/phobos/std_algorithm_iteration.html#.substitute.substitute i
understand that a call to substitute() can be made on the result of
substitute().

Thanks

BTW: can sourcecode be formated in this forum somehow?
Jan 11 2020
next sibling parent Martin Brezl <martin.brzenska googlemail.com> writes:
On Saturday, 11 January 2020 at 17:10:02 UTC, Martin Brezl wrote:
 Hi,

 i have a function like this:
 ```
[...]
 auto result = content.substitute(searches.front,replace);
	for(size_t i=1; i < searches.length; i++) {
		searches.popFront();
		result = result.substitute(searches.front,replace);
       }
 [...]
`result = result.to!string.substitute(searches.front,replace);` Convertring result to string solves the problem - but i do not understand why the Example "Multiple substitutes" from the docs is working.
Jan 11 2020
prev sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Saturday, 11 January 2020 at 17:10:02 UTC, Martin Brezl wrote:
 Hi,

 i have a function like this:
 ```
 import std.algorithm.iteration : substitute;
 //...
 string replace(string content, string[] searches , string 
 replace) {
 	
 	if(searches.empty) return content;

 	auto result = content.substitute(searches.front,replace);
 	for(size_t i=1; i < searches.length; i++) {
 		searches.popFront();
 		result = result.substitute(searches.front,replace);
 	}
         //...
         return "example return";
 }
 ```
The issue is the double assigned result. auto result = content.substitute(searches.front,replace); result = result.substitute(searches.front,replace); `substitute` is going to return a template range typed off `content` then it uses that type to perform another substitution. `content` and `result` don't have the same type.
Jan 11 2020
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
You can also turn your function into a fold.

auto searches = ["1", "2"];
writeln (searches.fold!((a, b)  => a.substitute(b, 
"number").to!string)("come 1 come 2")) ;
Jan 11 2020