Thread overview
Cannot reduce an empty iterable w/o an explicit seed value
Nov 09, 2017
Vino
Nov 09, 2017
Nicholas Wilson
Nov 14, 2017
Vino
Nov 09, 2017
Nicholas Wilson
November 09, 2017
Hi All,

  Request your help, when i execute the below line of code i am getting an error message as "Cannot reduce an empty iterable w/o an explicit seed value" , The below lie of code will iterate several file system and will report the size of the folder (level 1) which is greater than 10GB.


Program:
auto coSizeDirList (string FFs, int SizeDir) {
	float subdirTotal;
	float subdirTotalGB;
	Array!string Result;
	auto dFiles = Array!string ((dirEntries(FFs, SpanMode.shallow).filter!(a => a.isDir))[].map!(a => a.name));
	foreach (d; parallel(dFiles[], 1)) {
	auto SdFiles = Array!float ((dirEntries(join(["\\\\?\\", d]), SpanMode.depth).filter!(a => a.isFile))[].map!(a => to!float(a.size)));
	{
	subdirTotalGB = ((reduce!((a,b) => a + b)(SdFiles)) / 1024 / 1024 / 1024);
				}
 if (subdirTotalGB > SizeDir) {
Result.insertBack(d); Result.insertBack(to!string(subdirTotalGB));
			}
				}
			return Result;
}

From,
Vino.B
November 09, 2017
On Thursday, 9 November 2017 at 12:40:49 UTC, Vino wrote:
> Hi All,
>
>   Request your help, when i execute the below line of code i am getting an error message as "Cannot reduce an empty iterable w/o an explicit seed value" , The below lie of code will iterate several file system and will report the size of the folder (level 1) which is greater than 10GB.
>
>
> Program:
> auto coSizeDirList (string FFs, int SizeDir) {
> 	float subdirTotal;
> 	float subdirTotalGB;
> 	Array!string Result;
> 	auto dFiles = Array!string ((dirEntries(FFs, SpanMode.shallow).filter!(a => a.isDir))[].map!(a => a.name));
> 	foreach (d; parallel(dFiles[], 1)) {
> 	auto SdFiles = Array!float ((dirEntries(join(["\\\\?\\", d]), SpanMode.depth).filter!(a => a.isFile))[].map!(a => to!float(a.size)));
> 	{
> 	subdirTotalGB = ((reduce!((a,b) => a + b)(SdFiles)) / 1024 / 1024 / 1024);
> 				}
>  if (subdirTotalGB > SizeDir) {
> Result.insertBack(d); Result.insertBack(to!string(subdirTotalGB));
> 			}
> 				}
> 			return Result;
> }
>
> From,
> Vino.B

The problem is
subdirTotalGB = ((reduce!((a,b) => a + b)(SdFiles)) / 1024 / 1024 / 1024);
with reduce you need to give it a seed (an initial value to start with).
See
https://dlang.org/phobos/std_algorithm_iteration.html#.reduce

> int[] arr = [ 1, 2, 3, 4, 5 ];
> // Sum all elements
> auto sum = reduce!((a,b) => a + b)(0, arr);
> writeln(sum); // 15
> 
> // Sum again, using a string predicate with "a" and "b"
> sum = reduce!"a + b"(0, arr);
> writeln(sum); // 15

To your actual use case, you can do:

foreach (d; parallel(dFiles[], 1)) {
float subdirTotalGB = dirEntries(join(["\\\\?\\", d]), SpanMode.depth)
    .filter!(a => a.isFile))
    .map!(a => to!float(a.size)))
    .fold!((a, b) => a + b)(0) // Provide an explicit seed.

    if (subdirTotalGB > SizeDir) {
        Result.insertBack(d);
        Result.insertBack(to!string(subdirTotalGB));
    }
}


November 09, 2017
On Thursday, 9 November 2017 at 12:40:49 UTC, Vino wrote:
> Hi All,
>
>   Request your help, when i execute the below line of code i am getting an error message as "Cannot reduce an empty iterable w/o an explicit seed value" , The below lie of code will iterate several file system and will report the size of the folder (level 1) which is greater than 10GB.

The reason you get this is because when evaluating an empty directory there are no files, so it is like you are trying to do
>    [].sum
which can give no sensible result.

November 14, 2017
On Thursday, 9 November 2017 at 13:24:45 UTC, Nicholas Wilson wrote:
> On Thursday, 9 November 2017 at 12:40:49 UTC, Vino wrote:
>> [...]
>
> The problem is
> subdirTotalGB = ((reduce!((a,b) => a + b)(SdFiles)) / 1024 / 1024 / 1024);
> with reduce you need to give it a seed (an initial value to start with).
> See
> https://dlang.org/phobos/std_algorithm_iteration.html#.reduce
>
>> [...]
>
> To your actual use case, you can do:
>
> foreach (d; parallel(dFiles[], 1)) {
> float subdirTotalGB = dirEntries(join(["\\\\?\\", d]), SpanMode.depth)
>     .filter!(a => a.isFile))
>     .map!(a => to!float(a.size)))
>     .fold!((a, b) => a + b)(0) // Provide an explicit seed.
>
>     if (subdirTotalGB > SizeDir) {
>         Result.insertBack(d);
>         Result.insertBack(to!string(subdirTotalGB));
>     }
> }

Hi,

 Thank you very much and I wanted to use reduce function instead of fold for accuracy purpose so i just added the below line and it worked.

Code:
float x;
x = 0;
{subdirTotalGB = ((reduce!((a,b) => a + b)(x, SdFiles)) / 1024 / 1024 / 1024);}