Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 09, 2017 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. */ } // ------------- |
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to codephantom | 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
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to rjframe | 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.
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to codephantom | 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
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to SimonN | 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;
}
// -------
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to codephantom | 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
}
```
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to rjframe | On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote:
> 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
Use .release to obtain the underlying array. No need to do another allocation!
```
numbers.take(8).sort.release;
```
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | 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.
|
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to rjframe | On Saturday, 9 December 2017 at 14:05:36 UTC, rjframe wrote: > 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. Yeah, you are very welcome. It's a bit hidden in the docs: https://dlang.org/phobos/std_range.html#SortedRange |
December 09, 2017 Re: Sort in return statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | 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);
}
// -----------
|
Copyright © 1999-2021 by the D Language Foundation