std.container & ranges

Jonathan M Davis jmdavisProg at gmx.com
Sun Oct 30 13:28:02 PDT 2011


On Sunday, October 30, 2011 20:53:02 Max Wolter wrote:
> Hello there.
> 
> Thank you very much for the explanation.
> 
> However, while I really liked the concept of ranges in Andrei's book and
> a lot of it seems intuitive and faster than using iterators, I can't
> shake the feeling that in this case, it's just unnecessarily convoluted.
> 
> Maybe it's just the fact that the container library is still very basic,
> but I don't think I should go through such a complicated procedure to
> remove an known element from a list. It's just not a "very simple" or
> intuitive solution, which is something I came to love D for thus far.

You would be doing exactly the same thing in C++ except that it would be with 
an iterator rather than a range. You would use find to find the iterator to the 
element that you wanted and then you'd pass that to the list's erase function. 
It is only more complicated in D in that you get a range which _starts_ with 
the element that you want (essentially, you get the iterator to that element 
plus the end iterator for the list), so if you want to remove only the first 
element, you take it from the front of the range. Other than that, it's the 
same as in C++. You can't remove an element from a list in C++ by giving that 
element to the list anymore than you can in D. In both cases, you need an 
iterator or a range.

So, in comparison to C++, there's no significant difference. Now, Java does have 
a remove function which will take an element and remove the first occurence of 
that element from a list, and we could theoretically add one, but why? It 
would just be duplicating the functionality that find already gives. Java 
doesn't use iterators the way the C++ does, and it doesn't have ranges, so it 
_can't_ have a find function the way that C++ and D do, but D can. And in some 
cases, find can do it more efficiently than your loop could have.

I grant you that if you're not used to using find like this in C++ (and far, 
far too many C++ programmers use loops instead of find - in part because pre-
C++11, there were no lambdas and any time you need a custom comparison 
function, it's a pain to get one), then it's not immediately intuitive, but 
it's far more flexible and powerful than removing elements by giving the 
element to a remove function on the list. And if you really want to use a 
loop, then you still can. You just can't use foreach.

for(auto r = organism[]; !r.empty; r.popFront())
{
    if(r.front.x == x && r.front.y == y)
    {
        organism.stableLinearRemove(take(r, 1));
        break;
    }
}

but that's a lot more verbose than simply using find, and as I said, in at 
least some cases, find can be more efficient than simply looping, since it's 
optimized for finding elements.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list