Re: Sort in return statement
On Saturday, 9 December 2017 at 14:49:28 UTC, Seb wrote: randomSample doesn't sort its returned range Not by design, however, because it samples in the order that the elements appear, *if* those elements are already sorted (whether by design or explicately sorted), then the results of the randomsample are also implicitly already sorted ;-)
Re: Sort in return statement
On Saturday, 9 December 2017 at 14:42:44 UTC, codephantom wrote: After lots of reading, and testing, I managed to get a simple, one liner ;-) (doesn't seem like .release is needed though.) FYI .release is only possible on a SortedRange and then yields the underlying range. randomSample doesn't sort its returned range, but I am glad to hear this worked for you.
Re: Sort in return statement
On Saturday, 9 December 2017 at 14:18:00 UTC, Seb wrote: Yeah, you are very welcome. It's a bit hidden in the docs: Yes. Thanks for that. After lots of reading, and testing, I managed to get a simple, one liner ;-) (doesn't seem like .release is needed though.) // --- auto draw8Numbers() { import std.meta : aliasSeqOf; import std.range : iota; import std.random : randomSample; return randomSample([ aliasSeqOf!(iota(1,46)) ], 8); } // ---
Re: Sort in return statement
On Saturday, 9 December 2017 at 14:05:36 UTC, rjframe wrote: On Sat, 09 Dec 2017 07:32:42 +, Seb wrote: Use .release to obtain the underlying array. No need to do another allocation! ``` numbers.take(8).sort.release; ``` I did not realize that was there; thanks. Yeah, you are very welcome. It's a bit hidden in the docs: https://dlang.org/phobos/std_range.html#SortedRange
Re: Sort in return statement
On Sat, 09 Dec 2017 07:32:42 +, Seb wrote: > > Use .release to obtain the underlying array. No need to do another > allocation! > > ``` > numbers.take(8).sort.release; > ``` I did not realize that was there; thanks.
Re: Sort in return statement
On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: On Sat, 09 Dec 2017 02:34:29 +, codephantom wrote: Anyone got ideas on how to get sort() working in the *return* statement? // ushort[] draw8Numbers() { import std.meta : aliasSeqOf; import std.range : iota; ushort[] numbers = [ aliasSeqOf!(iota(1,46)) ]; import std.random : randomShuffle; randomShuffle(numbers); import std.range : take; import std.algorithm.sorting : sort; return numbers.take(8); /* ok */ //return sort(numbers.take(8)); /* I want this, but it won't work. */ } // - `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan Use .release to obtain the underlying array. No need to do another allocation! ``` numbers.take(8).sort.release; ```
Re: Sort in return statement
On Saturday, 9 December 2017 at 03:24:52 UTC, codephantom wrote: On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan That's it! Thanks Ryan. You can also return a lazy range: ``` auto draw8Numbers() { import std.meta : aliasSeqOf; import std.range : iota, take; ushort[] numbers = [ aliasSeqOf!(iota(1,46)) ]; import std.random : randomShuffle; randomShuffle(numbers); import std.algorithm.sorting : sort; return sort(numbers[].take(8)); } void main() { import std.array; ushort[] nbrs = draw8Numbers.array; // evaluated after return, during assingment } ```
Re: Sort in return statement
On Saturday, 9 December 2017 at 04:31:33 UTC, SimonN wrote: Yes, this works, and your algorithm would even accept arbitary random-access ranges, not merely arrays. Would be nice if I could do it all as a 'one liner': // int[] draw8Numbers() { import std.algorithm.sorting : sort; import std.random : randomShuffle; import std.meta : aliasSeqOf; import std.range : iota; import std.range : take; import std.array : array; // return a sorted array of 8 random numbers, between 1..45 inclusive. return sort(randomShuffle([ aliasSeqOf!(iota(1,46)) ]).take(8)).array; } // ---
Re: Sort in return statement
On Saturday, 9 December 2017 at 03:24:52 UTC, codephantom wrote: On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan That's it! Thanks Ryan. Yes, this works, and your algorithm would even accept arbitary random-access ranges, not merely arrays. But since we start explicitly with a ushort[] that this function has allocated just for this algorithm, we could save the extra allocation by the final call to array(). // ushort[] numbers = ... randomShuffle(numbers); import std.algorithm.sorting : sort; numbers = numbers[0 .. 8]; sort(numbers); return numbers; sort(numbers) does two things: (1) affect the underlying data, (2) return an input range with extra information that this returned range is sorted. But in our example, we don't need to allocate a fresh array from (2). We can return the sorted data from (1), this is already in array-form. -- Simon
Re: Sort in return statement
On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan That's it! Thanks Ryan.
Re: Sort in return statement
On Sat, 09 Dec 2017 02:34:29 +, codephantom wrote: > Anyone got ideas on how to get sort() working in the *return* > statement? > > // > > ushort[] draw8Numbers() > { > import std.meta : aliasSeqOf; > import std.range : iota; > ushort[] numbers = [ aliasSeqOf!(iota(1,46)) ]; > > import std.random : randomShuffle; > randomShuffle(numbers); > > import std.range : take; > import std.algorithm.sorting : sort; > return numbers.take(8); /* ok */ > //return sort(numbers.take(8)); /* I want this, but it won't > work. */ > > } > > // - `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan
Sort in return statement
Anyone got ideas on how to get sort() working in the *return* statement? // ushort[] draw8Numbers() { import std.meta : aliasSeqOf; import std.range : iota; ushort[] numbers = [ aliasSeqOf!(iota(1,46)) ]; import std.random : randomShuffle; randomShuffle(numbers); import std.range : take; import std.algorithm.sorting : sort; return numbers.take(8); /* ok */ //return sort(numbers.take(8)); /* I want this, but it won't work. */ } // -