Thread overview
fold on empty range
Feb 17, 2021
Rumbu
Feb 17, 2021
Mitacha
Feb 17, 2021
Rumbu
Feb 17, 2021
Mitacha
Feb 17, 2021
Rumbu
February 17, 2021
In the expression below:

return matchAll(content, keywordsPattern)
            .map!(a => a.hit.stripLeft("[").strip("]"))
            .fold!((a, b) => a ~ "," ~ b)
            .splitter(',')
            .map!(a => a.stripLeft("\" ").strip("\" "))
            .filter!(a => !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':'))
            .array
            .sort
            .uniq;


fold is throwing an exception if the result of the previous map is empty. Is there any way to express something to convince fold to return the empty range received from map?

Of course, I know I can test for empty in a separate expression, but I'd like to keep my expression flow as it is.
February 17, 2021
On Wednesday, 17 February 2021 at 09:21:47 UTC, Rumbu wrote:
> In the expression below:
>
> return matchAll(content, keywordsPattern)
>             .map!(a => a.hit.stripLeft("[").strip("]"))
>             .fold!((a, b) => a ~ "," ~ b)
>             .splitter(',')
>             .map!(a => a.stripLeft("\" ").strip("\" "))
>             .filter!(a => !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':'))
>             .array
>             .sort
>             .uniq;
>
>
> fold is throwing an exception if the result of the previous map is empty. Is there any way to express something to convince fold to return the empty range received from map?
>
> Of course, I know I can test for empty in a separate expression, but I'd like to keep my expression flow as it is.

I think you can try using `fold` with seed value:
```
             .map!(a => a.hit.stripLeft("[").strip("]"))
             .fold!((a, b) => a ~ "," ~ b)("")
             .splitter(',')
```
it'll use empty string as first element in range.

BTW perheps you could use `joinner` instead of this `fold` to join values with ",".
February 17, 2021
On Wednesday, 17 February 2021 at 10:15:10 UTC, Mitacha wrote:

> it'll use empty string as first element in range.
>
> BTW perheps you could use `joinner` instead of this `fold` to join values with ",".

Thanks for that. I thought to joiner too, but it doesn't work. I need fold to take a list of strings and concatenate them. Basically I read comma separated keywords from various sources and i want to iterate through all of them. If you know other method without the involved allocation of fold...

.map!(a => a.hit.stripLeft("[").strip("]"))     //"k1,k2", "k3,k4" ...
.fold!((a, b) => a ~ "," ~ b)("")               //"k1,k2,k3,k4,..."
.splitter(',')                                  //"k1", "k2", "k3", "k4", ...,
.map!(a => a.stripLeft("\" '").strip("\" '"))
.filter!(a => a.length && !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':'))
.array
.sort
.uniq;

February 17, 2021
On Wednesday, 17 February 2021 at 11:38:45 UTC, Rumbu wrote:
> On Wednesday, 17 February 2021 at 10:15:10 UTC, Mitacha wrote:
>
>> it'll use empty string as first element in range.
>>
>> BTW perheps you could use `joinner` instead of this `fold` to join values with ",".
>
> Thanks for that. I thought to joiner too, but it doesn't work. I need fold to take a list of strings and concatenate them. Basically I read comma separated keywords from various sources and i want to iterate through all of them. If you know other method without the involved allocation of fold...
>
> .map!(a => a.hit.stripLeft("[").strip("]"))     //"k1,k2", "k3,k4" ...
> .fold!((a, b) => a ~ "," ~ b)("")               //"k1,k2,k3,k4,..."
> .splitter(',')                                  //"k1", "k2", "k3", "k4", ...,
> .map!(a => a.stripLeft("\" '").strip("\" '"))
> .filter!(a => a.length && !a.any!(b => b == ' ' || b == '\\' || b == '/' || b == ':'))
> .array
> .sort
> .uniq;

If you replace `fold` and `splitter` with this, then it doesn't allocate:
```
auto fn() @nogc {
    return only("k1,k2", "k3,k4")
        .map!(x => x.splitter(","))
        .joiner;
}

void main() {
   auto range = fn();
   range.writeln;
}
```
February 17, 2021
On Wednesday, 17 February 2021 at 12:58:29 UTC, Mitacha wrote:
> On Wednesday, 17 February 2021 at 11:38:45 UTC, Rumbu wrote:
>> [...]
>
> If you replace `fold` and `splitter` with this, then it doesn't allocate:
> ```
> auto fn() @nogc {
>     return only("k1,k2", "k3,k4")
>         .map!(x => x.splitter(","))
>         .joiner;
> }
>
> void main() {
>    auto range = fn();
>    range.writeln;
> }
> ```
Wow, thanks a lot.