digitalmars.D.learn - Sort in return statement
- codephantom (17/17) Dec 08 2017 Anyone got ideas on how to get sort() working in the *return*
- rjframe (7/30) Dec 08 2017 `sort` returns a SortedRange of ushorts, not an array of ushorts. Make i...
- codephantom (3/10) Dec 08 2017 That's it!
- SimonN (18/31) Dec 08 2017 Yes, this works, and your algorithm would even accept arbitary
- codephantom (17/19) Dec 08 2017 Would be nice if I could do it all as a 'one liner':
- user1234 (20/33) Dec 08 2017 You can also return a lazy range:
- Seb (6/38) Dec 08 2017 Use .release to obtain the underlying array. No need to do
- rjframe (2/9) Dec 09 2017 I did not realize that was there; thanks.
- Seb (3/12) Dec 09 2017 Yeah, you are very welcome. It's a bit hidden in the docs:
- codephantom (14/15) Dec 09 2017 Yes. Thanks for that.
- Seb (4/7) Dec 09 2017 FYI .release is only possible on a SortedRange and then yields
- codephantom (5/6) Dec 09 2017 Not by design, however, because it samples in the order that the
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. */ } // -------------
Dec 08 2017
On Sat, 09 Dec 2017 02:34:29 +0000, 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
Dec 08 2017
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; ``` --RyanThat's it! Thanks Ryan.
Dec 08 2017
On Saturday, 9 December 2017 at 03:24:52 UTC, codephantom wrote:On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: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`sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --RyanThat's it! Thanks Ryan.
Dec 08 2017
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; } // -------
Dec 08 2017
On Saturday, 9 December 2017 at 03:24:52 UTC, codephantom wrote:On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: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 } ````sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --RyanThat's it! Thanks Ryan.
Dec 08 2017
On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote:On Sat, 09 Dec 2017 02:34:29 +0000, codephantom wrote:Use .release to obtain the underlying array. No need to do another allocation! ``` numbers.take(8).sort.release; ```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
Dec 08 2017
On Sat, 09 Dec 2017 07:32:42 +0000, 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.
Dec 09 2017
On Saturday, 9 December 2017 at 14:05:36 UTC, rjframe wrote:On Sat, 09 Dec 2017 07:32:42 +0000, Seb wrote:Yeah, you are very welcome. It's a bit hidden in the docs: https://dlang.org/phobos/std_range.html#SortedRangeUse .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.
Dec 09 2017
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); } // -----------
Dec 09 2017
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.
Dec 09 2017
On Saturday, 9 December 2017 at 14:49:28 UTC, Seb wrote:randomSample doesn't sort its returned rangeNot 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 ;-)
Dec 09 2017