Thread overview
Seed Value for reduce function
Dec 10, 2017
Vino
Dec 10, 2017
Vino
Dec 10, 2017
Jonathan M Davis
Dec 10, 2017
Vino
Dec 10, 2017
Ali Çehreli
Dec 11, 2017
Vino
December 10, 2017
Hi All,

  Request you help on how to add the seed value for the reduce function, below is the scnerio

Program 1 : Works

import std.algorithm;
void main () {
int[] ara = [1,2 ,3];
auto sum1 = ara.reduce!((a,b) => a + b);
writeln(sum1);
}

Program 2: Works
void main () {
int[] arrb = [];
auto sum1 = reduce!((a,b) => a + b)(0 , arb);
writeln(sum1);
}

So how to add seed value for the below code as same as program 1 without calling the seed value and array at the end rather than calling it as arc.reduce!((a,b) => a + b);

void main () {
int[] arc = [];
auto sum1 = arc.reduce!((a,b) => a + b);
writeln(sum1);
}

From,
Vino.B
December 10, 2017
On Sunday, 10 December 2017 at 00:39:07 UTC, Vino wrote:
> Hi All,
>
>   Request you help on how to add the seed value for the reduce function, below is the scnerio
>
> Program 1 : Works
>
> import std.algorithm;
> void main () {
> int[] ara = [1,2 ,3];
> auto sum1 = ara.reduce!((a,b) => a + b);
> writeln(sum1);
> }
>
> Program 2: Works
> void main () {
> int[] arrb = [];
> auto sum1 = reduce!((a,b) => a + b)(0 , arb);
> writeln(sum1);
> }
>
> So how to add seed value for the below code as same as program 1 without calling the seed value and array at the end rather than calling it as arc.reduce!((a,b) => a + b);
>
> void main () {
> int[] arc = [];
> auto sum1 = arc.reduce!((a,b) => a + b);
> writeln(sum1);
> }
>
> From,
> Vino.B

Another example: The below code does errors out with the below error in there are any empty folders, else it works fine.

import std.stdio;
import std.file;
import std.container;
import std.algorithm;
ulong Size = 10;

auto SdFiles = Array!ulong(dirEntries("C:\\Temp\\BACKUP", SpanMode.depth).map!(a => a.size).reduce!((a,b) => a + b))[].filter!(a => a  > Size);

Error:
object.Exception@C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(2794): Cannot reduce an empty input range w/o an explicit seed value.

From,
Vino.B
December 09, 2017
On Sunday, December 10, 2017 00:39:07 Vino via Digitalmars-d-learn wrote:
> Hi All,
>
>    Request you help on how to add the seed value for the reduce
> function, below is the scnerio
>
> Program 1 : Works
>
> import std.algorithm;
> void main () {
> int[] ara = [1,2 ,3];
> auto sum1 = ara.reduce!((a,b) => a + b);
> writeln(sum1);
> }
>
> Program 2: Works
> void main () {
> int[] arrb = [];
> auto sum1 = reduce!((a,b) => a + b)(0 , arb);
> writeln(sum1);
> }
>
> So how to add seed value for the below code as same as program 1
> without calling the seed value and array at the end rather than
> calling it as arc.reduce!((a,b) => a + b);
>
> void main () {
> int[] arc = [];
> auto sum1 = arc.reduce!((a,b) => a + b);
> writeln(sum1);
> }

So, basically, you're trying to use reduce with UFCS, and that doesn't work in the case where you want to provide an explicit seed value? In that's the case, then use fold:

https://dlang.org/phobos/std_algorithm_iteration.html#fold

reduce predates UFCS in the language, so there wasn't really a reason to prefer having the range as the first argument at the time. fold has since been added to fix that problem. They're identical except for the order of arguments (in fact, fold just calls reduce internally).

- Jonathan M Davis

December 10, 2017
On Sunday, 10 December 2017 at 01:42:46 UTC, Jonathan M Davis wrote:
> On Sunday, December 10, 2017 00:39:07 Vino via Digitalmars-d-learn wrote:
>> [...]
>
> So, basically, you're trying to use reduce with UFCS, and that doesn't work in the case where you want to provide an explicit seed value? In that's the case, then use fold:
>
> https://dlang.org/phobos/std_algorithm_iteration.html#fold
>
> reduce predates UFCS in the language, so there wasn't really a reason to prefer having the range as the first argument at the time. fold has since been added to fix that problem. They're identical except for the order of arguments (in fact, fold just calls reduce internally).
>
> - Jonathan M Davis

Hi Jonathan,

 Tried with fold even then it is failing same as reduce with the same error when there is empty folder

auto SdFiles = Array!ulong(dirEntries(d, SpanMode.depth).map!(a => a.size).fold!((a,b) => a + b))[].filter!(a => a  > Size);

From,
Vino.B
December 09, 2017
On 12/09/2017 06:19 PM, Vino wrote:

>   Tried with fold even then it is failing same as reduce with the same error when there is empty folder
> 
> auto SdFiles = Array!ulong(dirEntries(d, SpanMode.depth).map!(a => a.size).fold!((a,b) => a + b))[].filter!(a => a  > Size);

When no seed value is specified, fold (and reduce) take the first element as the seed. When the range is empty, then there is a run-time failure:

object.Exception@/usr/include/dmd/phobos/std/algorithm/iteration.d(2794): Cannot reduce an empty input range w/o an explicit seed value.

The solution is to provide an explicit seed value:

import std.container;
import std.file;
import std.algorithm;

void main() {
    const d = "/tmp/empty_folder";
    const Size = 42;
    auto SdFiles = Array!ulong(dirEntries(d, SpanMode.depth).map!(a => a.size).fold!((a,b) => a + b)(size_t(0)))[].filter!(a => a  > Size);
}

I chose size_t(0) but you can use a variable, size_t.init, etc.

Ali
December 11, 2017
On Sunday, 10 December 2017 at 06:01:49 UTC, Ali Çehreli wrote:
> On 12/09/2017 06:19 PM, Vino wrote:
>
>> [...]
>
> When no seed value is specified, fold (and reduce) take the first element as the seed. When the range is empty, then there is a run-time failure:
>
> object.Exception@/usr/include/dmd/phobos/std/algorithm/iteration.d(2794): Cannot reduce an empty input range w/o an explicit seed value.
>
> The solution is to provide an explicit seed value:
>
> import std.container;
> import std.file;
> import std.algorithm;
>
> void main() {
>     const d = "/tmp/empty_folder";
>     const Size = 42;
>     auto SdFiles = Array!ulong(dirEntries(d, SpanMode.depth).map!(a => a.size).fold!((a,b) => a + b)(size_t(0)))[].filter!(a => a  > Size);
> }
>
> I chose size_t(0) but you can use a variable, size_t.init, etc.
>
> Ali

Hi Ali,
 Thank you very much, was able to apply your logic which resolved the issue.

From,
Vino.B