std.container & ranges
    Steven Schveighoffer 
    schveiguy at yahoo.com
       
    Mon Oct 31 07:35:31 PDT 2011
    
    
  
On Sun, 30 Oct 2011 06:38:30 -0400, Max Wolter <awishformore at gmail.com>  
wrote:
> Hello there.
>
> I seem to be having problems wrapping my head around how to use the  
> ranges in the context of containers in phobos. Specifically, I can't  
> seem to figure out how to remove an element from a linked list.
>
>           foreach(cell; organism)
>           {
>              if(cell.x == x && cell.y == y)
>              {
>                 organism.stableLinearRemove(cell);
>                 break;
>              }
>           }
>
> mind.d(123): Error: function  
> std.container.SList!(Cell).SList.linearRemove (Range r) is not callable  
> using argument types (Cell)
> mind.d(123): Error: cannot implicitly convert expression (cell) of type  
> cell.Cell to Take!(Range)
>
> I somehow get the feeling such a basic operation should just...work?
I offer an alternative collection library to std.container which has a  
simpler (IMO) interface and features.
There is specifically a feature for removal during iteration.  It would  
look like this:
foreach(ref doRemove, cell; &organism.purge)
{
    doRemove = cell.x == x && cell.y == y; // flag indicating the current  
element should be removed
    // note, not necessary to break here
    if(doRemove)
       break;
}
Note two things, removal during iteration is directly supported, meaning  
it does not derail the iteration; and removal during iteration is a quick  
operation (O(lg(n)) or better) in terms of the individual removal.
If you have a linked list, you can also do it the "range" way:
organism.remove(find!((a){return a.x == x && a.y ==  
y;})(organism[]).begin);
begin is an accessor for a dcollections range that returns a reference  
(cursor) to the first element in the range.
Note also that dcollections' linked list is doubly-linked, so removal is  
O(1).
-Steve
    
    
More information about the Digitalmars-d-learn
mailing list