Too complicated code for generating a random string?
monarch_dodra
monarchdodra at gmail.com
Sat Feb 23 05:49:54 PST 2013
On Saturday, 23 February 2013 at 13:02:38 UTC, Jens Mueller wrote:
>
> I think this version also looks good:
> void main()
> {
> auto randomLetter = () => randomSample(letters, 1,
> letters.length).front;
> writeln(iota(10).map!(_ => randomLetter()));
> }
>
> Which makes me think Phobos is convenient enough in this use
> case. Just
> finding a simple way to use it can be a burden. It should be
> improved
> with better documentation.
>
> Jens
No offense, but I think that's horrible. No matter how you put
it, you should keep in mind that the strength of these ranges is
being able do stuff lazily.
The final product of what you have is a horrible contraption of
chained ranges, that go out of their way just to pick a random
char for you.
Not to mention, you are creating a randomSample per character,
which is simply not the way it is designed to be used. Generating
an entire new range just to generate a random letter...? At
least: use uniform instead:
auto randomLetter = () => letters[uniform (0, letters.length);
Still, even with that, IMO, the end product is bug prone, not
very clear, and horribly inefficient. I'd hate to be the one to
have to maintain this down the pipe... And at the end of the day,
you'd still need to add an "array" at the end if you want to put
it in a string anyways.
--------
Honestly, what happened to doing it by hand? It's more robust,
cleaner, easy to understand...
string randomString;
{
auto app = Appender!string();
foreach(_ ; 0 .. 10)
app.put(letters[uniform(0, letters.length)]);
randomString = app.data;
}
This is the "easy and safe" version. You could make it even more
simple with a pre-allocate dchar:
string randomString;
{
auto tmp = new dchar[](10);
foreach(ref c ; tmp)
c = letters[uniform(0, letters.length)];
randomString = tmp.to!string();
}
Or, if you know your letters are all ascii, it gets even more
simple and efficient:
string randomString;
{
auto tmp = new char[](10);
foreach(ref char c ; tmp)
c = letters[uniform(0, letters.length)];
randomString = cast(string)letters;
}
All those scope blocks I put in are not mandatory. At the end of
the day, it is 4 lines of code. Very efficient, and the intent is
crystal clear.
I know it's not very exciting code, they do say good code is
boring code.
More information about the Digitalmars-d
mailing list