2013-05-17 2 views
4

В моем источнике данных могут быть дубликаты ключей со значениями.Удалить одно значение из NameValueCollection

typeA : 1 

typeB : 2 

typeA : 11 

Я решил использовать NameValueCollection как это позволяет ввод дубликатов ключей.

Я хочу удалить определенную пару ключей \ из коллекции, но NameValueCollection.Remove(key) удаляет все значения, связанные с указанным ключом.

  1. Есть ли способ, чтобы удалить одну пару ключа \ значение из NameValueCollection, ИЛИ
  2. Есть ли лучшая коллекция в C#, который соответствует моим данным

[EDIT 1]

Во-первых, спасибо за все ответы :)

Я думаю, я должен был упомянуть tha t моим источником данных является XML.

Я использовал System.Xml.Linq.XDocument для запроса типа, а также было удобно удалить конкретное значение.

Теперь, мой вопрос, для данных большого размера, использует XDocument, хороший выбор, учитывая производительность? Если не то, что другие альтернативы (возможно, вернуться к NameValueCollection и используя один из методов, указанных для удаления данных)

+0

Не Я думаю, что это не будет работать с индексом элемента, вероятно, вам нужно попробовать другим способом –

+0

Try Dictionary. –

+2

Try 'List >' –

ответ

-1

Вы можете использовать словарь коллекции вместо:

Dictionary<string, int> dictionary = new Dictionary<string, int>(); 
dictionary.Add("typeA", 1); 
dictionary.Add("typeB", 1); 

При попытке вставить type: 11 это будет throw, поскольку Key уже существует. Таким образом, вы можете ввести новый ключ для вставки этих данных.

Обратитесь к этому Tutorial за дополнительной помощью.

0

Вы можете преобразовать его в Hashtable

  var x = new NameValueCollection(); 
      x.Add("a", "1"); 
      x.Add("b", "2"); 
      x.Add("a", "1"); 
      var y = x.AllKeys.ToDictionary(k => k, k=>x[k]); 
+1

Словарь будет содержать значения ["a", "1,1"] и ["b", "2"]. Вероятно, это не то, что Айман после. – user707727

0

сделать свой собственный метод, он работает для меня -

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)); 
} 

затем вызвать его в списке, как -

list.Remove(key,value); //Pass the key value... 
+0

Это решение работает только в том случае, если 'EqualityComparer .Default' и' EqualityComparer .Default' дают правильные результаты. –

2

Идея хранения нескольких значений с одним и тем же ключом является чем-то странным. Но я думаю, что вы можете получить все значения с помощью GetValues, а затем удалить тот, который вам не нужен, и поместить его обратно с помощью Set, а затем последующих методов Add. Для этого вы можете сделать отдельный метод метода расширения.

0

Возможно, не самый лучший способ, но ....

public class SingleType 
{ 
    public string Name; 
    public int Value; 
} 

List<SingleType> typeList = new List<SingleType>(); 
typeList.Add (new SingleType { Name = "TypeA", Value = 1 }); 
typeList.Add (new SingleType { Name = "TypeA", Value = 3 }); 

typeList.Remove (typeList.Where (t => t.Name == "TypeA" && t.Value == 1).Single()); 
+0

'Single()' генерирует исключение, если в списке нет одного элемента. Это должно быть в порядке: 'var val = typeList.Where (t => t.Name ==" TypeA "&& t.Value == 1) .SingleOrDefault(); if (val! = null) typeList.Remove (val); ' –

+0

Да, извините, следовало бы упомянуть, что очень быстро сбил код ... однако, может быть, было бы полезно выбросить (пойманное) исключение, чтобы указать, что есть была попытка удалить недействительные данные IMO. – Andrew

+0

Да, это зависит от того, считает ли пользователь «попытку удаления недействительных данных» _exceptional_ –

1

NameValueCollection действительно не позволяют иметь несколько записей с тем же ключом. Он просто объединяет новые значения существующих ключей в список значений, разделенных запятыми (см. NameValueCollection.Add.

Таким образом, действительно действительно одно значение для ключа.Возможно, вы можете получить значение, разделяющее их на «,» и удалить оскорбительное значение.

Edit: @ElDog is correct, there is a GetValues method which does this for you so no need to split.

Лучше варианта Я думаю, что было бы использовать Dictionary<string, IList<int>> или Dictionary<string, ISet<int>> для хранения значений как дискретный ERM, значение

Смежные вопросы