tags:

views:

133

answers:

4

I'm thinking of doing:

for(LinkedListNode<MyClass> it = myCollection.First; it != null; it = it.Next)
{
    if(it.Value.removalCondition == true)
        it.Value = null;
}

What I'm wondering is if simply pointing the it.Value to null actually gets rid of it.

A: 

Surely (with a linked list) you need to change the link.

Eg, if you want to remove B from the LL A-B-C, you need to change A's link to B to C.

I'll admit I'm not familiar with the .NET implementation of linked lists but hopefully that's a start for you.

Oli
right, i think i have to do a myCollection.Remove(it.Value) instead.
they changed my name
they changed my name: you can just do a myCollection.Remove(it) -- Remove has an overload which take a `LinkedListNode<T>` -- you don't need to pull out the Value.
itowlson
Running off to the collection like that seems a little resource intensive. If you know the sequence of nodes logic suggests you could do this more efficiently by telling the previous node to change its node to the current node's next node. Say that ten times fast.
Oli
Apparently the prev/next cursors are immutable. Seems a strange things to do for a double-linked list but what do I know? I'm just a cat.
Oli
If you use the method of @itowlson, don't forget to advance your `it` _before_ delete.
Vlad
Oli: nope, it's actually just as efficient provided he calls the `Remove(LinkedListNode<T>)` overload. This actually does exactly what you say, just updating the node's prev and next pointers. (You're right however that the `Remove<T>` overload *is* inefficient because then the collection has to locate the right node first.)
itowlson
A: 

You are changing the value pointed to by a LinkedListNode; beware that your list will contain a hole (empty node) now.

Instead of A - B - C you are going to have A - null - C, if you "delete" B. Is that what you want to achieve?

Vlad
A: 

I assume something like this is required

for ( LinkedListNode<MyClass> it = myCollection.First; it != null; it = it.Next ) {
  if ( it.Value.removalCondition == true ) {
    if ( it.Previous != null && it.Next != null ) {
      it.Next.Previous = it.Previous;
      it.Previous.Next = it.Next;
    } else if ( it.Previous != null )
      it.Previous.Next = it.Next;
    } else if ( it.Next != null )
      it.Next.Previous = it.Previous;
    it.Value = null;
  }
}
JDMX
Won't compile: Next and Previous are read-only. Just use Remove instead.
itowlson
A: 

If you can convert to using List<> rather than LinkedList<> then you can use the RemoveAll() operation. Pass an anonymous delegate like this;

List<string> list = new List<string>()
{
    "Fred","Joe","John"
};

list.RemoveAll((string val) =>
{
    return (0 == val.CompareTo("Fred"));
});

All this is using Linq extensions.

If you can't convert to using a list then you can use the ToList<>() method to convert it. But you'll then have to do some clear and insertion operations. Like this;

LinkedList<string> str = new LinkedList<string>();
str.AddLast("Fred");
str.AddLast("Joe");
str.AddLast("John");

List<string> ls = str.ToList();
ls.RemoveAll((string val) => val.CompareTo("Fred") == 0);
str.Clear();
ls.ForEach((string val) => str.AddLast(val));

If all this still isn't palatable then try doing a copy of the LinkedList like this;

LinkedList<string> str = new LinkedList<string>();
str.AddLast("Fred");
str.AddLast("Joe");
str.AddLast("John");

LinkedList<string> strCopy = new LinkedList<string>(str);
str.Clear();
foreach (var val in strCopy)
{
    if (0 != val.CompareTo("Fred"))
    {
        str.AddLast(val);
    }
}

I hope that helps.

Mark Milbourne