tags:

views:

902

answers:

5

How can I remove a item from list of KeyValuePair?

+11  A: 

If you have both the key and the value you can do the following

public static void Remove<TKey,TValue>(
  this List<KeyValuePair<TKey,TValue>> list,
  TKey key,
  TValue value) {
  return list.Remove(new KeyValuePair<TKey,TValue>(key,value)); 
}

This works because KeyValuePair<TKey,TValue> does not override Equality but is a struct. This means it uses the default value equality. This simply compares the values of the fields to test for equality. So you simply need to create a new KeyValuePair<TKey,TValue> instance with the same fields.

EDIT

To respond to a commenter, what value does an extension method provide here?

Justification is best seen in code.

list.Remove(new KeyValuePair<int,string>(key,value));
list.Remove(key,value);

Also in the case where either the key or value type is an anonymous type, an extension method is required.

EDIT2

Here's a sample on how to get KeyValuePair where one of the 2 has an anonymous type.

var map = 
  Enumerable.Range(1,10).
  Select(x => new { Id = x, Value = x.ToString() }).
  ToDictionary(x => x.Id);

The variable map is a Dicitonary<TKey,TValue> where TValue is an anonymous type. Enumerating the map will produce a KeyValuePair with the TValue being the same anonymous type.

JaredPar
Aside from the few syntax errors contained, what value is this extension method intending to provide?
Derek Greer
@Derek, removes the need to specify any generic arguments to a type definition when doing a remove. list.Remove(key,value) vs. list.Remove(new KeyValuePair<int,string>(key,value)). The former is much more concise. Don't think a -1 is worthy of a minor syntax error
JaredPar
I voted this answer down because I didn't feel the use of an extension method provided a clear, concise answer or added value, not due to the syntax errors.
Derek Greer
In response to the edited section, the provision of a slightly more convenient API is an obvious benefit in need of no such example. While more convenient, I would argue that the method signature of List.Remove(string, string) isn't particularly intention revealing. I would also question whether proper encapsulation was being performed if values were being removed in the number of places to make such a convenience worth while. [continued]
Derek Greer
That said, I'm curious about the second reason you provided which was to accommodate anonymous types. Can you provide an example of how a KeyValuePair<TKey, TValue> would be declared with an anonymous type for either the key or value? I've never had such a need or seen this technique used, but if possible I can definitely see a benefit in providing such an abstraction.
Derek Greer
In response to edit 2, technically that's a projection not a declaration. Nevertheless, this does demonstrate one way of solving the problem. As a nod to creativity, I'm removing my down vote. However, there is a simpler approach to this issue which I'll provide in an edit to my answer. I still question the usefulness of this approach though, due to the contention between the need for its frequent use to be beneficial and that its frequent use points to a code smell (i.e. why are items being removed from so many different places requiring an extension method to reduce the amount of coding?)
Derek Greer
A: 

Should be able to use the .Remove(), .RemoveAt(), or one of the other methods.

cloggins
A: 
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
    KeyValuePair<string, string> kvp = list[i];
    list.Remove(kvp);

or

    list.Remove(list[1]);

You must obtain a reference to the object you want to remove - that's why I found the item I'm looking for and assigned to a KeyValuePair - since you're telling it to remove a specific item.

A better solution might be to use a dictionary:

    Dictionary<string, string> d = new Dictionary<string, string>();
    if (d.ContainsKey("somekey")) d.Remove("somekey");

This allows you to remove by the key value instead of having to deal with the list not being indexed by the key.

Edit you may not have to get a KeyValuePair reference first. Still, a dictionary is probably a better way to go.

David Lively
A: 

To remove all items in the list by key:

myList.RemoveAll(x => x.Key.Equals(keyToRemove));
Jamie Ide
+2  A: 

Here are a few examples of removing an item from a list of KeyValuePair:

// Remove the first occurrence where you have key and value
items.Remove(new KeyValuePair<int, int>(0, 0));

// Remove the first occurrence where you have only the key
items.Remove(items.First(item => item.Key.Equals(0)));

// Remove all occurrences where you have the key
items.RemoveAll(item => item.Key.Equals(0));

EDIT

// Remove the first occurrence where you have the item
items.Remove(items[0]);
Derek Greer