www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - is it possible to sort a float range ?

reply someone <someone somewhere.com> writes:
Please, look for the line marked +++

This is a structure with a public property returning a (still 
unsorted) range built on-the-fly from already-set properties, a 
basic range from a to z with n step where some specific values 
can be added in-between. The range is a float which I am 
currently using for currency (horrible) and later plan to move it 
to decimal 10 or the like.

```d
public struct gudtRangeWhatIf {

    private float[] pnumValueCustom;
    private float pnumValueBaseLimit1;
    private float pnumValueBaseLimit2;
    private float pnumValueBaseStep;

    public float start()  property const { return 
pnumValueBaseLimit1; }
    public float end()  property const { return 
pnumValueBaseLimit2; }
    public float step()  property const { return 
pnumValueBaseStep; }

    public float[] range()  property const {

       float[] lnumRange;

       if (! (pnumValueBaseLimit1 == float.nan || 
pnumValueBaseLimit2 == float.nan || pnumValueBaseStep == 
float.nan)) {

          for (
             float lnumValue = pnumValueBaseLimit1;
             lnumValue <= pnumValueBaseLimit2;
             lnumValue += pnumValueBaseStep
             ) {

             lnumRange ~= lnumValue;

          }

       }

       foreach (float lnumValue; pnumValueCustom) {

          lnumRange ~= lnumValue;

       }

       return lnumRange; /// .sort!(r"a > b"c); /// doesn't work 
+++

    }

    this(
       in float lnumValueBaseLimit1,
       in float lnumValueBaseLimit2,
       in float lnumValueBaseStep
       ) {

       /// (1) given start limit > 0
       /// (2) given end limit > start limit
       /// (3) given step > 0

       if (lnumValueBaseLimit1 > 0f && lnumValueBaseLimit1 < 
lnumValueBaseLimit2 && lnumValueBaseStep > 0f) {

          pnumValueBaseLimit1 = lnumValueBaseLimit1;
          pnumValueBaseLimit2 = lnumValueBaseLimit2;
          pnumValueBaseStep = lnumValueBaseStep;

       }

    }

    public void addCustomValue(
       in float lnumValue
       ) {

       /// (1) given value > 0

       if (lnumValue > 0f) {

          pnumValueCustom ~= lnumValue;

       }

    }

}
```
Jun 23 2021
parent reply Jordan Wilson <wilsonjord gmail.com> writes:
On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote:
 Please, look for the line marked +++

 This is a structure with a public property returning a (still 
 unsorted) range built on-the-fly from already-set properties, a 
 basic range from a to z with n step where some specific values 
 can be added in-between. The range is a float which I am 
 currently using for currency (horrible) and later plan to move 
 it to decimal 10 or the like.

 [...]
```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```.
Jun 23 2021
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/23/21 6:30 PM, Jordan Wilson wrote:
 On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote:
 Please, look for the line marked +++

 This is a structure with a public property returning a (still 
 unsorted) range built on-the-fly from already-set properties, a basic 
 range from a to z with n step where some specific values can be added 
 in-between. The range is a float which I am currently using for 
 currency (horrible) and later plan to move it to decimal 10 or the like.

 [...]
```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```.
Use the `release` method: ```d return lnumRange.sort!(...).release; ``` -Steve
Jun 23 2021
next sibling parent Jordan Wilson <wilsonjord gmail.com> writes:
On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven Schveighoffer 
wrote:
 On 6/23/21 6:30 PM, Jordan Wilson wrote:
 On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote:
 [...]
```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```.
Use the `release` method: ```d return lnumRange.sort!(...).release; ``` -Steve
Wow...learn something new every day, cheers! Jordan
Jun 23 2021
prev sibling parent reply someone <someone somewhere.com> writes:
On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven Schveighoffer 
wrote:

 Use the `release` method:

 ```d
 return lnumRange.sort!(...).release;
 ```

 -Steve
Fantastic, issue solved, I previously used sort ascending even descending but first time on floats. So I went and searched phobos docs: auto release(); Releases the controlled range and returns it. Not much clarification there. Can you elaborate a bit if possible Steve ?
Jun 23 2021
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/23/21 7:07 PM, someone wrote:
 On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven Schveighoffer wrote:
 
 Use the `release` method:

 ```d
 return lnumRange.sort!(...).release;
 ```
Fantastic, issue solved, I previously used sort ascending even descending but first time on floats. So I went and searched phobos docs: auto release(); Releases the controlled range and returns it. Not much clarification there. Can you elaborate a bit if possible Steve ?
I think the purpose behind it is to say "here, now you have the original range back, so I won't guarantee it's sorted any more." I'm pretty sure it also clears out the source range in the sorted range, so you can no longer use the sortedness functions, but that's easily circumvented using `save`. I can't really defend the purpose/implementation of `SortedRange`, it's something in Phobos that I've complained about extensively in the past. -Steve
Jun 23 2021
parent reply mw <mingwu gmail.com> writes:
On Thursday, 24 June 2021 at 00:32:31 UTC, Steven Schveighoffer 
wrote:
 On 6/23/21 7:07 PM, someone wrote:
 On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven 
 Schveighoffer wrote:
 
 Use the `release` method:

 ```d
 return lnumRange.sort!(...).release;
 ```
Fantastic, issue solved, I previously used sort ascending even descending but first time on floats. So I went and searched phobos docs: auto release(); Releases the controlled range and returns it. Not much clarification there. Can you elaborate a bit if possible Steve ?
I think the purpose behind it is to say "here, now you have the original range back, so I won't guarantee it's sorted any more."
I for one still don't understand. guarantee? are you saying without the `release()` call, the sorted-ness is somehow guaranteed?
 I'm pretty sure it also clears out the source range in the 
 sorted range, so you can no longer use the sortedness 
 functions, but that's easily circumvented using `save`.
This `SortedRange` definitely need better documentation. E.g. users can easily convert their `sort()` code to D from Java or Python code after reading the doc.
 I can't really defend the purpose/implementation of 
 `SortedRange`, it's something in Phobos that I've complained 
 about extensively in the past.
(Sure, I'm not blaming you.)
Jun 23 2021
parent reply mw <mingwu gmail.com> writes:
On Thursday, 24 June 2021 at 00:47:28 UTC, mw wrote:
 On Thursday, 24 June 2021 at 00:32:31 UTC, Steven Schveighoffer

 This `SortedRange` definitely need better documentation. E.g. 
 users can easily convert their `sort()` code to D from Java or 
 Python code after reading the doc.
I think in most other popular language's std lib: container.sort(); or sort(container); is just one call, and the user will expect the `container` is sorted after the call. Hence, the confusion from the original post. If D want to convert more people from other more popular languages, it's better try to make this conversion as easy as possible.
Jun 23 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/23/21 6:09 PM, mw wrote:

 I think in most other popular language's std lib:

 container.sort();

 or

 sort(container);


 is just one call, and the user will expect the `container` is sorted
 after the call.
That's exactly the same in D. What's different is, D's sort() does not return the original array (more generally, "random access range").
 If D want to convert more people from other more popular languages, it's
 better try to make this conversion as easy as possible.
Agreed but this is not an example of that situation. Instead of calling release(), one can return the array as well: import std.algorithm; lnumRange.sort!(r"a > b"c); return lnumRange; I happen to like SortedRange. It's an interesting and useful experiment that constrains functionality. The problem with other languages, you can run "binary search" on any array (even if the array is not sorted. The correctness is left to the programmer, who is proven to be a source of bugs. Other languages will not complain at all... On the other hand, Phobos, with the help of SortedRange, protects the programmer from doing so: You can binary search only on a SortedRange, which is usually a cheap layer over an existing array or any other kind of RandomAccessRange. As a system programmer, I appreciate assumeSorted() as well, which allows me to tell the compiler that "this array is really sorted." So, I think SortedRange is very useful. Ali
Jun 23 2021
parent reply someone <someone somewhere.com> writes:
On Thursday, 24 June 2021 at 01:36:47 UTC, Ali Çehreli wrote:

       import std.algorithm;
       lnumRange.sort!(r"a > b"c);
       return lnumRange;
The above works OK. Funny thing indeed, at least to me, totally unexpected. ```d return lnumRange.sort!(r"a > b"c); /// does not work return lnumRange.sort!(r"a > b"c).release(); /// works ``` Intuitive ? Not a bit LoL ! (not complaining at all, just making fun of it)
Jun 23 2021
parent reply jfondren <julian.fondren gmail.com> writes:
On Thursday, 24 June 2021 at 02:33:42 UTC, someone wrote:
 On Thursday, 24 June 2021 at 01:36:47 UTC, Ali Çehreli wrote:

       import std.algorithm;
       lnumRange.sort!(r"a > b"c);
       return lnumRange;
The above works OK. Funny thing indeed, at least to me, totally unexpected. ```d return lnumRange.sort!(r"a > b"c); /// does not work return lnumRange.sort!(r"a > b"c).release(); /// works ``` Intuitive ? Not a bit LoL ! (not complaining at all, just making fun of it)
Most languages have either a void sort that mutates, or a non-mutating sort that returns the new array. This is true also of similar languages: C++, Nim, and Rust all void mutate. So the more experience you have with other languages, probably the more surprised you'll be by D's sort. This comes up in a few places with D, like the rest of range support in phobos, or dynamic arrays. - a thing seems to be a familiar feature - surprise! it's different in an important way - (period of grumbling) - ok, it's useful that it's like this
Jun 23 2021
parent someone <someone somewhere.com> writes:
On Thursday, 24 June 2021 at 05:39:22 UTC, jfondren wrote:

 - ok, it's useful that it's like this
Albeit (the grumbling and) the weirdness of it, this is exactly the reason why I am not complaining on such behavior -time will show me.
Jun 24 2021
prev sibling parent someone <someone somewhere.com> writes:
On Wednesday, 23 June 2021 at 22:30:29 UTC, Jordan Wilson wrote:

 ```sort``` returns a ```SortedRange```, and I believe you wish 
 to return a float.
no, I want to return the range (full of floats) sorted -think it amount or prices or whatever
Jun 23 2021