www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - randomSample

reply David Held <dmd wyntrmute.com> writes:
How do I get an array from randomSample()?

int[] source = [ ... ];
int[] sample = randomSample(source, 3);

src\main.d(30): Error: cannot implicitly convert expression 
(randomSample(source, 3u)) of type RandomSample!(int[], void) to int[]

I get that RandomSample is a struct which implements the necessary 
interface to work with foreach.  But the fact that this struct is 
considered a proprietary implementation detail of std.random is a 
constant source of frustration for me.  Quite a few D libraries use this 
trick, but the opacity of these data structures make it impossible for 
users to know exactly how to use them outside of the one or two examples 
given in the documentation.  I don't know how to improve the situation, 
other than documenting them explicitly rather than treating them as a 
magical black box.

In the mean time, can anyone suggest a solution to the above, short of 
actually iterating over it?  I suppose someone will say to use map!().

Dave
May 17 2014
next sibling parent David Held <dmd wyntrmute.com> writes:
On 5/17/2014 9:18 PM, David Held wrote:
 How do I get an array from randomSample()?

 int[] source = [ ... ];
 int[] sample = randomSample(source, 3);

 src\main.d(30): Error: cannot implicitly convert expression
 (randomSample(source, 3u)) of type RandomSample!(int[], void) to int[]
 [...]
Even worse, foreach is brittle: foreach (i, a; randomSample(source, 3)) src\main.d(30): Error: cannot infer argument types If I remove the index variable, it works. But I really need the index too. Dave
May 17 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Sunday, 18 May 2014 at 04:19:05 UTC, David Held wrote:
 How do I get an array from randomSample()?

 int[] source = [ ... ];
 int[] sample = randomSample(source, 3);

 src\main.d(30): Error: cannot implicitly convert expression 
 (randomSample(source, 3u)) of type RandomSample!(int[], void) 
 to int[]

 I get that RandomSample is a struct which implements the 
 necessary interface to work with foreach.  But the fact that 
 this struct is considered a proprietary implementation detail 
 of std.random is a constant source of frustration for me.  
 Quite a few D libraries use this trick, but the opacity of 
 these data structures make it impossible for users to know 
 exactly how to use them outside of the one or two examples 
 given in the documentation.  I don't know how to improve the 
 situation, other than documenting them explicitly rather than 
 treating them as a magical black box.

 In the mean time, can anyone suggest a solution to the above, 
 short of actually iterating over it?  I suppose someone will 
 say to use map!().

 Dave
You need to use the function array from std.array. import std.array; int[] source = [ ... ]; int[] sample = randomSample(source, 3).array(); Array has the ability to turn any range into an array, and it's generally how you convert from these structs (which generally implement a range interface) returned by most range-based functions in D. It can be a bit confusing at first, but returning a range struct is much more flexible than returning a simple array of values.
May 17 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Meta:

 You need to use the function array from std.array.

 import std.array;

 int[] source = [ ... ];
 int[] sample = randomSample(source, 3).array();
In some cases it's also useful to use std.algorithm.copy: void main() { import std.stdio, std.algorithm, std.random, std.array, std.range; immutable int[9] source = iota(10, 100, 10).array; source.writeln; int[3] sample; source[].randomSample(sample.length).copy(sample[]); sample.writeln; } Bye, bearophile
May 18 2014