Why is std.algorithm so complicated to use?

Dmitry Olshansky dmitry.olsh at gmail.com
Tue Jul 10 05:53:13 PDT 2012


On 10-Jul-12 15:37, Jacob Carlborg wrote:
> On 2012-07-10 12:05, Dmitry Olshansky wrote:
>
>> and what type has the return of map ? Let me guess - array.
>
> Yes, and that is what I _want_.

Too bad, as there is no need to make an array when you map something.

  I have no need for streaming data from
> the network into a linked list, filter it and then convert it to an
> array (or something similar). I want to start with an array and end with
> an array.
>

Then you need something like transform. Anyway the result of map should 
be sortable it's a bug.

>> Please count the number of allocations in your paste of Ruby.
>
> Probably four (if you count the initial allocation for the array
> literal). Plus a couple for the "to_s" method.
>

Now scale the problem to at least ~ 10^6 ...

> But I can use the same methods and modify the array in place instead:
>
> a = [5, 3, 5, 6, 8]
> a.uniq!
> a.map!{ |e| e.to_s }
> a.sort!
> p a
>
> Prints:
>
> ["3", "5", "6", "8"]
>
> The corresponding D version would be:
>
> auto a = [5, 3, 5, 6, 8].uniq.map!(x => x.to!(string)).array.sort.array;

The last array is unnecessary as sort is in-place.
Also why would you not sort before map? It'd be faster this way as it's 
sorting integers.

Thus it's only 2 and one of them is literal. The map can't be sorted 
because uniq produces lazy bidirectional range. Thus you turn it into 
array as simple as that.

My version would be:

auto a = [5, 3, 5, 6, 8].sort().uniq().map!(x => x.to!(string))();

fixed?

> writeln(a);
>
> I'm guessing that's three allocations. But that doesn't even work, it
> prints:
>
> ["3", "5", "5", "6", "8"]

Because uniq work only on sorted ranges? Have you tried reading docs?
"
Iterates unique consecutive elements of the given range (functionality 
akin to the uniq system utility). Equivalence of elements is assessed by 
using the predicate pred, by default "a == b". If the given range is 
bidirectional, uniq also yields a bidirectional range.
"
Though it doesn't explicitly mentions it, the example is:

int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));

And it's a general knowledge that you can't run uniq in reasonable speed 
on unsorted sequence. (it'd take O(N^2) which is worse then sorting and 
then doing unique).

-- 
Dmitry Olshansky




More information about the Digitalmars-d mailing list