On Tuesday, July 10, 2012 08:51:29 Jacob Carlborg wrote: > On 2012-07-09 22:23, Ali Çehreli wrote: > > And a quick fix is to make an array first: > > > > auto str = ["foo", "bar"].map!(x => x)().array(); > > > > Also note the added () for map, which is needed when compiled with > > -property. > > If I first have to convert it to an array, then sort and then convert it > to an array again. Isn't that missing the whole point of ranges.
The problem is that map is lazy, so it can't be a random access range, and sort requires a random access range. If map were eager, it would just be creating an array anyway. But you don't need to convert it to an array again after sorting it. sort returns a SortedRange so that functions such as find can know that it's sorted and take advantage of it, but it sorts in place (SortedRange is just a wrapper around the range which was passed in and copies no data), so once you've called sort on your array, it's sorted. You can just ignore the return type if you're not looking to pass it to a function which would take advantage of the fact that it's sorted. But since SortedRange _isn't_ lazy (it's just a wrapper around the newly sorted original range, after all), it's still a random access range and will work with functions which require that (unlike map). You only end up with a range with fewer capabilities than the original when the algorithm itself intrinsicly requires it, and that sort of range is generally lazy (since it's more efficient that way, and making it non-lazy would be equivalent to wrapping it in a call to array anyway). - Jonathan M Davis