.sort vs sort(): std.algorithm not up to the task?

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jun 7 19:25:17 PDT 2017


On Thursday, June 08, 2017 01:57:47 Andrew Edwards via Digitalmars-d-learn 
wrote:
> Ranges may be finite or infinite but, while the destination may
> be unreachable, we can definitely tell how far we've traveled. So
> why doesn't this work?
>
> import std.traits;
> import std.range;
>
> void main()
> {
>      string[string] aa;
>
>      // what others have referred to as
>      // standard sort works but is deprecated
>      //auto keys = aa.keys.sort;
>
>      // Error: cannot infer argument types, expected 1 argument,
> not 2
>      import std.algorithm: sort;
>      auto keys = aa.keys.sort();
>
>      // this works but why should I have to?
>      //import std.array: array;
>      //auto keys = aa.keys.sort().array;
>
>      foreach (i, v; keys){}
> }

Ranges do not support iterating with an index. The workaround if you want to
have an index with ranges and foreach, then you should use lockstep:

http://dlang.org/phobos/std_range.html#lockstep

e.g.

foreach(i, v; lockstep(iota!size_t(0), s))
{}

or

foreach(i, v; lockstep(iota(0), s))
{}

if you don't mind i being an int instead of a size_t.

Now, with your example, there are two other solutions that are even easier.
sort() sorts the range that it's given in place but returns a wrapper range
so that other algorithms can recognize the range as sorted. So, if you did

auto keys = aa.keys;
sort(keys);

foreach(i; v)
{}

then it will work just fine, because you're still dealing with an array.
Alternatively, you could use SortedRange's release function to get the array
out of the SortedRange (though note if you do that, you shouldn't then use
the SortedRange anymore, since it does a move call to actual move the
wrapped range out of the SortedRange). e.g.

auto keys = aa.keys.sort().release();

foreach(i; v)
{}

and that would allow you to still do it in one line.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list