Removing an element from a list or array

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 6 12:41:49 PDT 2014


On Wednesday, 6 August 2014 at 19:01:26 UTC, Patrick wrote:
> I feel dumb.  I've been searching for how to do this, and each 
> page or forum entry I read makes me more confused.
>
> Let's say I have a list of values (Monday, Tuesday, Wednesday, 
> Thursday, Friday).  I can store this list in an Slist, Dlist, 
> Array etc -- any collection is fine.
>
> I decide I want to remove Thursday from the list.
>
> How?  I see that linearRemove is meant to do this, but that 
> takes a range.  How do I get a range of 'Thursday'?

Slicing a container gives you a range for that container, and 
it's that type that needs to be used to remove elements (either 
that, or that type wrapped with std.range.Take), since otherwise, 
the container wouldn't know which elements you were trying to 
remove - just their values.

You need to use std.algorithm.find to find the element that you 
want to remove, in which case, you have a range starting at that 
element (but it contains everything after it too). So, you used 
std.range.take to take the number of elements that you want from 
the range, and then you pass that result to linearRemove. e.g.

import std.algorithm;
import std.container;
import std.range;

void main()
{
     auto arr = Array!string("Monday", "Tuesday", "Wednesday",
                             "Thursday", "Friday");
     auto range = arr[];
     assert(equal(range, ["Monday", "Tuesday", "Wednesday",
                          "Thursday", "Friday"]));
     auto found = range.find("Thursday");
     assert(equal(found, ["Thursday", "Friday"]));
     arr.linearRemove(found.take(1));
     assert(equal(arr[], ["Monday", "Tuesday", "Wednesday", 
"Friday"]));
}

C++ does it basically the same way that D does, but it's actually 
one place where iterators are cleaner, because you can just pass 
the iterator to erase, whereas with a range, that would remove 
all of the elements after that element, which is why you need 
take, which makes it that much more complicated.

Using opSlice like that along with range-based functions like 
find which don't return a new range type will always be what 
you'll need to do in the general case, but it would definitely be 
nice if we added functions like removeFirst to remove elements 
which matched a specific value so that the simple use cases 
didn't require using find.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list