NameValueCollection vs Dictionary<string,string> [duplicate] - c#

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
IDictionary<string, string> or NameValueCollection
Any reason I should use Dictionary<string,string> instead of NameValueCollection?
(in C# / .NET Framework)
Option 1, using NameValueCollection:
//enter values:
NameValueCollection nvc = new NameValueCollection()
{
{"key1", "value1"},
{"key2", "value2"},
{"key3", "value3"}
};
// retrieve values:
foreach(string key in nvc.AllKeys)
{
string value = nvc[key];
// do something
}
Option 2, using Dictionary<string,string>...
//enter values:
Dictionary<string, string> dict = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"},
{"key3", "value3"}
};
// retrieve values:
foreach (KeyValuePair<string, string> kvp in dict)
{
string key = kvp.Key;
string val = kvp.Value;
// do something
}
For these use cases, is there any advantage to use one versus the other? Any difference in performance, memory use, sort order, etc.?

They aren't semantically identical. The NameValueCollection can have duplicate keys while the Dictionary cannot.
Personally if you don't have duplicate keys, then I would stick with the Dictionary. It's more modern, uses IEnumerable<> which makes it easy to mingle with Linq queries. You can even create a Dictionary using the Linq ToDictionary() method.

NameValueCollection is string typed whereas Dictionary leverages generics to allow type variance. See Benefits of Generics.

Dictionary will be much faster. NameValueCollection allows duplicate keys. Which could be bad in certain situations, or desired in other. Dictionary does not allow duplicate keys.
From: http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
The Dictionary<(Of <(TKey, TValue>)>)
generic class provides a mapping from
a set of keys to a set of values. Each
addition to the dictionary consists of
a value and its associated key.
Retrieving a value by using its key is
very fast, close to O(1), because the
Dictionary<(Of <(TKey, TValue>)>)
class is implemented as a hash table.

Related

Creating dictionaries with pre-defined keys C#

I'm looking for a way to define a dictionary for reuse. ie. I can create the dictionary object without having to populate it with the values I want.
Here is what I have currently (note code not tested, just example)
public Dictionary<string, string> NewEntryDictionary()
{
Dictionary<string, string> dic = new Dictionary<string, string>();
// populate key value pair
foreach(string name in Enum.GetNames(typeof(Suits))
{
dic.Add(name, "");
}
return dic;
}
The end result should be a new dictionary object with a predefined set of keys.
But I want to avoid doing it this way.
It's not really clear whether you're concerned about the amount of code you've written, or the efficiency of it. From an efficiency perspective, it's fine - it's O(N), but that's hard to avoid if you're populating a dictionary with N entries.
You can definitely make the source code shorter though, using LINQ:
public Dictionary<string, string> NewEntryDictionary()
{
return Enum.GetNames(typeof(Suits)).ToDictionary(name => name, name => "");
}
That won't be any more efficient, of course... it's just shorter code.
If you do ONLY want to save values according to your enum, use
Dictionary<Suits,String> instead of Dictionary<String,String>
Everything else, Jon already said. Use LinQ for a bit more "fancy" look. But that does not do better performance

Cast all keys in dictionary to uppercase

This is probably a very simple question but google has let me down sofar and keeps pointing me towards python solutions.
I have a webpage where applciations/users can supply querystringparameters.To Retrieve the querystring parameters I use the following code:
IDictionary<string, string> qStrings = HtmlPage.Document.QueryString;
to check the presence of a specified key, I use the following code:
if (!String.IsNullOrEmpty(qStrings["PARAM1"]))
{}
Knowing our users, i'm expecting them to give parameterkeys as follows: "Param1", "param1", "pArAm1"
How can simply cast every key in a dictionary to uppercase without iterating each key-valuepair?
Or how can i alter the qStrings["PARAM1"] so it ignores the case?
You can use StringComparer to find keys ignoring their case:
var qStrings = new Dictionary<string, string>(
HtmlPage.Document.QueryString,
StringComparer.OrdinalIgnoreCase)
Simplest Way
qStrings = qStrings .ToDictionary(k => k.Key.ToUpper(), k => k.Value.ToUpper());
Maybe you can do it like below:
Dictionary<string, string> qStrings = new Dictionary<string, string>();
foreach (var a in qStrings.Keys)
{
switch (a.ToUpper())
{
case "PARAM1":
break;
}
}
Without iterating is not possible. No matter what approach you use there is going to be some sort of iteration. The this is you need to limit the insertion of the data to a single unified casing rather than allowing users to input all sorts of casing.
Taking your example: "Param1", "param1", "pArAm1", a key will be created for each single one of these as they are treated as separate entities. The best way to handle that is to force the casing at the insertion rather than when querying for values.
For example:
void AddToDictionary(string key, string value)
{
qStrings[key.ToUpper()] = value;
}

Multi key dictionary where only 1 key is needed to retrieve object

There are several places on the internet that talk about having multy key dictionary such as in:
Multi-key dictionary in c#?
Or
Multi-key dictionaries (of another kind) in C#?
I am looking for a multi key dictionary that will enable me to retrieve the object that I am looking for as long as I provide just one key. In other words If I where to have:
// multyKeyDictionary = instance of a multikeydictionary
multyKeyDictionary.add(key1, key2, someObject);
then I will like to be able to retrive someObject as:
multyKeyDictionary[key1]; or multyKeyDictionary[key2];
Well, I don't understand why don't you just use regular dictionary and add object twice with different keys.
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("key1", obj);
dict.Add("key2", obj);
// dict["key1"] == dict["key2"]

A dictionary with multiple entries with the same key [duplicate]

This question already has answers here:
C# dictionary - one key, many values
(15 answers)
Closed 8 years ago.
I need a Dictionary like object that can store multiple entries with the same key. Is this avaliable as a standard collection, or do I need to roll my own?
To clarify, I want to be able to do something like this:
var dict = new Dictionary<int, String>();
dict.Add(1, "first");
dict.Add(1, "second");
foreach(string x in dict[1])
{
Console.WriteLine(x);
}
Output:
first
second
In .NET 3.5 you can use a Lookup instead of a Dictionary.
var items = new List<KeyValuePair<int, String>>();
items.Add(new KeyValuePair<int, String>(1, "first"));
items.Add(new KeyValuePair<int, String>(1, "second"));
var lookup = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
foreach (string x in lookup[1])
{
Console.WriteLine(x);
}
The Lookup class is immutable. If you want a mutable version you can use EditableLookup from MiscUtil.
I would recommend doing something like this:
var dict = new Dictionary<int, HashSet<string>>();
dict.Add(1, new HashSet<string>() { "first", "second" });
Dictionary<T,K> does not support such behavior and there's no collection in the base class library providing such behavior. The easiest way is to construct a composite data structure like this:
var data = new Dictionary<int, List<string>>();
As the second parameter you should use a collection which provides the qualities you are looking for, i.e. stable order ⇒ List<T>, fast access HashSet<T>, etc.
You definitely want to use NameValueCollection:
using System.Collections.Specialized;
NameValueCollection nvc = new NameValueCollection();
nvc.Add("pets", "Dog");
nvc.Add("pets", "Rabbit");
Console.WriteLine(nvc["pets"]);
//returns Dog,Rabbit
What you're looking for isn't actually a Dictionary in the traditional sense (see Associative Array).
There's no class, as far as I'm aware, that offers this in the framework (System.Linq.Lookup doesn't expose a constructor), but you could create a class yourself that implements ILookup<TKey, TElement>
You could perhaps use a Dictionary on your primary key, in which each element is a List or other collection on your secondary key. To add an item to your data structure, see if the primary key exists. If not, create a new single-item list with your Value and store it in the dictionary. If the primary key does exist, add your Value to the list that's in the dictionary.

How to insert an item into a key/value pair object?

I just need to be able to insert a key/value pair into an object at a specific position. I'm currently working with a Hashtable which, of course, doesn't allow for this functionality. What would be the best approach?
UPDATE: Also, I do need the ability to lookup by the key.
For example (oversimplified and pseudocoded but should convey the point):
// existing Hashtable
myHashtable.Add("somekey1", "somevalue1");
myHashtable.Add("somekey2", "somevalue2");
myHashtable.Add("somekey3", "somevalue3");
// Some other object that will allow me to insert a new key/value pair.
// Assume that this object has been populated with the above key/value pairs.
oSomeObject.Insert("newfirstkey","newfirstvalue");
List<KeyValuePair<string, string>> kvpList = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("Key1", "Value1"),
new KeyValuePair<string, string>("Key2", "Value2"),
new KeyValuePair<string, string>("Key3", "Value3"),
};
kvpList.Insert(0, new KeyValuePair<string, string>("New Key 1", "New Value 1"));
Using this code:
foreach (KeyValuePair<string, string> kvp in kvpList)
{
Console.WriteLine(string.Format("Key: {0} Value: {1}", kvp.Key, kvp.Value);
}
the expected output should be:
Key: New Key 1 Value: New Value 1
Key: Key 1 Value: Value 1
Key: Key 2 Value: Value 2
Key: Key 3 Value: Value 3
The same will work with a KeyValuePair or whatever other type you want to use..
Edit -
To lookup by the key, you can do the following:
var result = stringList.Where(s => s == "Lookup");
You could do this with a KeyValuePair by doing the following:
var result = kvpList.Where (kvp => kvp.Value == "Lookup");
Maybe the OrderedDictonary will help you out.
Do you need to look up objects by the key? If not, consider using List<Tuple<string, string>> or List<KeyValuePair<string, string>> if you're not using .NET 4.
I would use the Dictionary<TKey, TValue> (so long as each key is unique).
EDIT: Sorry, realised you wanted to add it to a specific position. My bad. You could use a SortedDictionary but this still won't let you insert.
You could use an OrderedDictionary, but I would question why you would want to do that.
Use a linked list. It was designed for this exact situation.
If you still need the dictionary O(1) lookups, use both a dictionary and a linked list.
Hashtables are not inherently sorted, your best bet is to use another structure such as a SortedList or an ArrayList

Categories