Re: Sort in return statement

2017-12-09 Thread codephantom via Digitalmars-d-learn

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

2017-12-09 Thread Seb via Digitalmars-d-learn

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

2017-12-09 Thread codephantom via Digitalmars-d-learn

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

2017-12-09 Thread Seb via Digitalmars-d-learn

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

2017-12-09 Thread rjframe via Digitalmars-d-learn
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

2017-12-08 Thread Seb via Digitalmars-d-learn

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

2017-12-08 Thread user1234 via Digitalmars-d-learn

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

2017-12-08 Thread codephantom via Digitalmars-d-learn

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

2017-12-08 Thread SimonN via Digitalmars-d-learn

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

2017-12-08 Thread codephantom via Digitalmars-d-learn

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

2017-12-08 Thread rjframe via Digitalmars-d-learn
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

2017-12-08 Thread codephantom via Digitalmars-d-learn
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. */


}

// -