Thread overview | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 23, 2013 Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Hi, I'd like to sample with replacement. But found no simple way. In particular I want to generate a random string of given letters, say std.ascii.letters. Anybody a simpler version than auto randomString = repeat('a').take(10).map!(c => randomSample(letters, 1, letters.length))().joiner(); ? Jens |
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jens Mueller | On 02/22/2013 04:23 PM, Jens Mueller wrote:
> Hi,
>
> I'd like to sample with replacement. But found no simple way.
> In particular I want to generate a random string of given letters, say
> std.ascii.letters.
>
> Anybody a simpler version than
>
> auto randomString = repeat('a').take(10).map!(c => randomSample(letters, 1, letters.length))().joiner();
>
> ?
>
> Jens
Here is another way:
import std.stdio;
import std.algorithm;
import std.ascii;
import std.random;
import std.range;
auto pickOne(R)(R range)
// insert template constraints here ... :)
{
return range[uniform(0, range.length)];
}
void main()
{
writeln(iota(10).map!((_) => pickOne(letters)));
}
Ali
|
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli: > auto pickOne(R)(R range) > // insert template constraints here ... :) > { > return range[uniform(0, range.length)]; > } That's the function choice() I'd like in Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=4851 Note that: range[uniform(0, range.length)]; is written more compactly as: range[uniform(0, $)]; > void main() > { > writeln(iota(10).map!((_) => pickOne(letters))); > } Instead of "(_)" I think it's better to use a simpler "_". That's another commonly useful function, often named table(), similar to map() but doesn't pass an index to the callable: http://reference.wolfram.com/mathematica/ref/Table.html So it becomes something like: 10.table!({ return letters.choice; }).writeln; Bye, bearophile |
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 02/22/2013 05:07 PM, bearophile wrote: > Ali Çehreli: > >> auto pickOne(R)(R range) >> // insert template constraints here ... :) >> { >> return range[uniform(0, range.length)]; >> } > > That's the function choice() I'd like in Phobos: > http://d.puremagic.com/issues/show_bug.cgi?id=4851 Agreed. > Note that: > range[uniform(0, range.length)]; > > is written more compactly as: > range[uniform(0, $)]; Good point. I would think that $ must be "out in the open" to work that way. >> void main() >> { >> writeln(iota(10).map!((_) => pickOne(letters))); >> } > > Instead of "(_)" I think it's better to use a simpler "_". Mine evolved from the earlier buggy ()=> then I inserted an underscore without realizing to remove the parentheses. > That's another commonly useful function, often named table(), similar to > map() but doesn't pass an index to the callable: > > http://reference.wolfram.com/mathematica/ref/Table.html I did need such a function in the past. I have been thinking about the name 'generate' but if 'table' is common already, why not. :) > So it becomes something like: > > 10.table!({ return letters.choice; }).writeln; > > Bye, > bearophile Ali |
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2/22/13 10:07 PM, bearophile wrote:
> That's another commonly useful function, often named table(), similar to
> map() but doesn't pass an index to the callable:
>
> http://reference.wolfram.com/mathematica/ref/Table.html
>
> So it becomes something like:
>
> 10.table!({ return letters.choice; }).writeln;
Couldn't map! be used with a delegate that doesn't receive any arguments?
|
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | Ary Borenszweig:
>> 10.table!({ return letters.choice; }).writeln;
>
> Couldn't map! be used with a delegate that doesn't receive any arguments?
I think map() requires a callable that receives one argument.
table() doesn't need the iota() as map(), it accepts one or more numerical arguments, so it's able to generate 2D arrays, 3D arrays, etc.:
table!(() => letters.choice)(3, 4, 5).writeln;
Bye,
bearophile
|
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli wrote:
> On 02/22/2013 04:23 PM, Jens Mueller wrote:
> >Hi,
> >
> >I'd like to sample with replacement. But found no simple way.
> >In particular I want to generate a random string of given letters, say
> >std.ascii.letters.
> >
> >Anybody a simpler version than
> >
> >auto randomString = repeat('a').take(10).map!(c => randomSample(letters, 1, letters.length))().joiner();
> >
> >?
> >
> >Jens
>
> Here is another way:
>
> import std.stdio;
> import std.algorithm;
> import std.ascii;
> import std.random;
> import std.range;
>
> auto pickOne(R)(R range)
> // insert template constraints here ... :)
> {
> return range[uniform(0, range.length)];
> }
>
> void main()
> {
> writeln(iota(10).map!((_) => pickOne(letters)));
> }
Thanks that looks better.
Phobos misses a pickOne function.
Jens
|
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote:
> Ary Borenszweig:
>
> >>10.table!({ return letters.choice; }).writeln;
> >
> >Couldn't map! be used with a delegate that doesn't receive any arguments?
>
> I think map() requires a callable that receives one argument.
>
> table() doesn't need the iota() as map(), it accepts one or more
> numerical arguments, so it's able to generate 2D arrays, 3D arrays,
> etc.:
>
> table!(() => letters.choice)(3, 4, 5).writeln;
This looks almost like a Cartesian product but only specifying the
sizes.
I assume you have an enhancement request? Couldn't find it.
Jens
|
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jens Mueller | Jens Mueller: >> table!(() => letters.choice)(3, 4, 5).writeln; > > This looks almost like a Cartesian product but only specifying the sizes. table() also takes a function, so it's closer to a map() or to minimallyInitializedArray() than to a Cartesian product :-) > I assume you have an enhancement request? Couldn't find it. I think I don't have an enhancement request on table(). Bye, bearophile |
February 23, 2013 Re: Too complicated code for generating a random string? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli wrote:
> On 02/22/2013 04:23 PM, Jens Mueller wrote:
> >Hi,
> >
> >I'd like to sample with replacement. But found no simple way.
> >In particular I want to generate a random string of given letters, say
> >std.ascii.letters.
> >
> >Anybody a simpler version than
> >
> >auto randomString = repeat('a').take(10).map!(c => randomSample(letters, 1, letters.length))().joiner();
> >
> >?
> >
> >Jens
>
> Here is another way:
>
> import std.stdio;
> import std.algorithm;
> import std.ascii;
> import std.random;
> import std.range;
>
> auto pickOne(R)(R range)
> // insert template constraints here ... :)
> {
> return range[uniform(0, range.length)];
> }
>
> void main()
> {
> writeln(iota(10).map!((_) => pickOne(letters)));
> }
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
|
Copyright © 1999-2021 by the D Language Foundation