automate tuple creation

forkit forkit at gmail.com
Fri Jan 21 22:25:32 UTC 2022


On Friday, 21 January 2022 at 21:56:33 UTC, H. S. Teoh wrote:
>
> What's the point of calling .dup here?  The only reference to 
> records is going out of scope, so why can't you just return it? 
>  The .dup is just creating extra work for nothing.
>
>
> T

good pickup. thanks ;-)

// ----

module test;
@safe:

import std.stdio : write, writef, writeln, writefln;
import std.range : iota, enumerate;
import std.array : array, byPair, Appender, appender;
import std.random : Random, unpredictableSeed, dice, randomCover;
import std.algorithm : map;
import std.conv : to;
import std.format;
import std.stdio : File;
import std.file : exists;
import std.exception : enforce;

debug { import std; }

Random rnd;
static this() {  rnd = Random(unpredictableSeed); }

void main(string[] args)
{
     int recordsNeeded, valuesPerRecord;
     string fname;

     if(args.length < 4)
     {
         recordsNeeded = 10; // default
         valuesPerRecord= 8; // default

         fname = "D:/rnd_records.txt"; // default
         //fname = "./rnd_records.txt"; // default
     }
     else
     {
         // assumes valid values being passed in ;-)
         recordsNeeded = to!int(args[1]);
         valuesPerRecord = to!int(args[2]);
         fname = args[3];
     }

     debug
         { writefln("%s records, %s values for record, will be 
written to file: %s", recordsNeeded, valuesPerRecord, fname); }
     else
         {
             enforce(!exists(fname), "Oop! That file already 
exists!");
             enforce(recordsNeeded <= 1_000_000_000, "C'mon! 
That's too many records!");
         }

     int[][int][] records = CreateDataSet(recordsNeeded, 
valuesPerRecord);

     ProcessDataSet(records, fname);

     writefln("All done. Check if records written to %s", fname);
}

int[][int][] CreateDataSet
(const(int) recordsNeeded, const(int) valuesPerRecord)
{
     const int iotaStartNum = 100_000_001;

     int[][int][] records;
     records.reserve(recordsNeeded);
     debug { writefln("records.capacity is %s", records.capacity); 
}

     foreach(i, id; iota(iotaStartNum, iotaStartNum + 
recordsNeeded).enumerate)
     {
         // NOTE: below does register with -profile=gc
         records ~= [ id: 
iota(valuesPerRecord).map!(valuesPerRecord => 
cast(int)rnd.dice(0.6, 1.4)).array ];
     }

     debug { writefln("records.length = %s", records.length); }
     return records;
}

// this creates a big string of 'formatted' records, and outputs 
that string to a file.
void ProcessDataSet
(in int[][int][] records, const(string) fname)
{
     auto file = File(fname, "w");
     scope(exit) file.close;

     Appender!string bigString = appender!string;
     bigString.reserve(records.length);
     debug { writefln("bigString.capacity is %s", 
bigString.capacity); }

     // NOTE: forward declaration required for this nested function
     void processRecord(const(int) id, const(int)[] values)
     {
         bigString ~= id.to!string ~ "," ~ values.format!"%(%s,%)" 
~ "\n";
     }

     foreach(ref const record; records)
     {
         foreach (ref rp; record.byPair)
         {
             processRecord(rp.expand);
         }
     }

     debug { writeln; writeln(bigString[].until("\n")); writeln; } 
// display just one record

     file.write(bigString[]);
}
// ----




More information about the Digitalmars-d-learn mailing list