what is the best way to ensure that optionValue is always unique in the following scenario?
public Dictionary<string, string> Dict = new Dictionary<string, string>();
foreach (string optionKey in i.options.Keys)
{
string optionValue = i.options.Values.ToString();
Dict.Add(optionKey, optionValue);
}
EDIT: i.options contains a key and a value pair. I need to ensure that for each key the corresponding value is added to the dictionary
EDIT2: corrected order of Dict.Add(optionKey, optionValue)
Just test for it:
if(!Dict.ContainsKey(optionValue))
Dict.Add(optionValue, optionKey)
Based on your variable names it looks like you have key and value reversed though, if optionKey is your lookup key it should be:
Dict.Add(optionKey, optionValue);
A cursory browsing of the MSDN documentation reveals that you can use the obvious method ContainsKey(string) to check to see if a dictionary contains a certain key.
In a Dictionary all keys are unique. If you want to prevent an exception when adding entries to the Dictionary, use
if (!Dict.ContainsKey(optionKey)) {
Dict.Add(optionKey, optionValue);
} else {
Debug.Print("Key '"+optionKey+"' already exists");
}
Depends how you want to handle duplicates.
E.g "last one wins"
foreach(...)
{
// Will overwrite an existing key
Dict[optionValue] = optionKey;
}
"First one wins":
foreach(...)
{
if (!Dict.ContainsKey(optionValue)) Dict.Add(optionValue, optionKey);
}
public Dictionary<string, string> Dict = new Dictionary<string, string>();
foreach (string optionKey in i.options.Keys)
{
string optionValue = i.options.Values.ToString();
if(!Dict.ContainsValue(optionValue))
Dict.Add(optionValue, optionKey);
}
See
http://msdn.microsoft.com/en-us/library/kw5aaea4(v=vs.100).aspx
If you are just worried about exceptions, then just use the item property:
Dict[optionValue] = optionKey;
MSDN: If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key.
Or if you really want to do the check, use the ContainsKey method to check
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
Other folks have been suggesting that you simply test to see if the key exists, and skip adding if it does. However, this may lead to lost data. You should create a custom class or type and use that with your dictionary like so:
public Dictionary< Guid, CustomObjectOrType > Dict = new
Dictionary< Guid, CustomObjectOrType >();
This way you can ensure that each key is unique (a Guid) while preserving all option values and option keys.
Related
There is Dictionary:
var dictionary1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{{"abc1", 1}, {"abC2", 2}, {"abc3", 3}};
I can get a value:
var value = dictionary1["Abc2"];
If search key "Abc2" I need to get the original key "abC2" and value 2.
How to get original case key by case insensitive key?
You can't do that, unfortunately. It would be entirely reasonable for Dictionary<TKey, TValue> to expose a bool TryGetEntry(TKey key, KeyValuePair<TKey, TValue> entry) method, but it doesn't do so.
As stop-cran suggested in comments, the simplest approach is probably to make each value in your dictionary a pair with the same key as the key in the dictionary. So:
var dictionary = new Dictionary<string, KeyValuePair<string, int>>(StringComparer.OrdinalIgnoreCase)
{
// You'd normally write a helper method to avoid having to specify
// the key twice, of course.
{"abc1", new KeyValuePair<string, int>("abc1", 1)},
{"abC2", new KeyValuePair<string, int>("abC2", 2)},
{"abc3", new KeyValuePair<string, int>("abc3", 3)}
};
if (dictionary.TryGetValue("Abc2", out var entry))
{
Console.WriteLine(entry.Key); // abC2
Console.WriteLine(entry.Value); // 2
}
else
{
Console.WriteLine("Key not found"); // We don't get here in this example
}
If this is a field in a class, you could write helper methods to make it simpler. You could even write your own wrapper class around Dictionary to implement IDictionary<TKey, TValue> but add an extra TryGetEntry method, so that the caller never needs to know what the "inner" dictionary looks like.
You can use following code that utilizes LINQ to get dictionary key value pair even when case is not matching for key.
NOTE: This code can be used for dictionary of any size, but it's most appropriate for smaller size dictionaries since the LINQ is basically checking each key value pair one by one as opposed to directly going to the desired key value pair.
Dictionary<string,int> dictionary1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{
{"abc1",1},
{"abC2",2},
{"abc3",3}
} ;
var value1 = dictionary1["ABC2"];//this gives 2, even though case of key does not macth
//use LINQ to achieve your requirement
var keyValuePair1 = dictionary1.SingleOrDefault (d => d.Key.Equals("Abc2", StringComparison.OrdinalIgnoreCase) );
var key1 = keyValuePair1.Key ;//gives us abC2
var value2 =keyValuePair1.Value;//gives us 2
It is such that I must return the key parts that add no value.
key states that I've written but I would like to have out of this one return is just VALUE.
I've looked at ContainsKey who are here on this page.
http://www.dotnetperls.com/dictionary
the way I put "PakkeidUnik" into the metadata field you can see here: https://stackoverflow.com/a/37605865/6115825
I therefore get hold of Value as you can see here:
return stripeCustomer.Metadata = new Dictionary<string, string>()
{
Dictionary["PakkeidUnik"];//HERE ARE ITS ERROR!
};
My error are here:
UPDATE
It's a bit unclear what you're asking, you but seem to say you want to get the value for that key (having already set the values per your other question).
You simply use the indexer and pass the key:
return stripeCustomer.Metadata["PakkeidUnik"]
How to use a dictionary is covered in the article you've found. You also might find the examples in the documentation useful.
You seem to be confusing the dictionary initiator syntax, and the syntax for reading the value from a dictionary based on a known key.
A dictionary can be initialised with values like this:
var dict = new Dictionary<string,string>()
{
{"Key1","Value1"},
{"Key2","Value2"}
}
If you then want to read one of the values by key you use this:
var value = dict["Key1"]; // value will contain "Value1"
See the code below:
stripeCustomer.Metadata = new Dictionary<string, string>()
{
{ "PakkeidUnik", "The Value You would like to return for key PakkeidUnik" }
};
return stripeCustomer.Metadata;
I've a Dictionary<string, string> specDic that have the resource strings <Key,Value>, when I change the language of the app, it got new Dictionary<string, string> newDic that have the strings of the new language, but sometimes in the newDic we don't have keys that already in the specDic, in other words doesn't translated, I need to override the specDic with the newDic without override the non-found keys, I tried the following:
foreach (var item in newDic)
{
specDic[item.Key] = item.Value;
}
But, I don't loved what I did, does someone can suggest me a new way using linq or somthing?
Thanks
Turn your logic around, and look for each key from your original dictionary instead:
foreach (var key in specDic.Keys)
{
if (newDic.ContainsKey(key))
{
specDic[key] = newDic[key];
}
}
Now, if newDic contains a key matching one in specDic, the corresponding value in specDic will be overridden (or replaced, rather) by the value from newDic.
Values (keys) in specDic for which there is no corresponding value in newDic will remain as they are.
My data source could have duplicate keys with values.
typeA : 1
typeB : 2
typeA : 11
I chose to use NameValueCollection as it enables entering duplicate keys.
I want to remove specific key\value pair from the collection, but NameValueCollection.Remove(key) removes all values associated with the specified key.
Is there a way to remove single key\value pair from a NameValueCollection,
OR
Is there a better collection in C# that fits my data
[EDIT 1]
First, thanks for all the answers :)
I think I should have mentioned that my data source is XML.
I used System.Xml.Linq.XDocument to query for type and also it was handy to remove a particular value.
Now, my question is, for large size data, is using XDocument a good choice considering the performance?
If not what are other alternatives (maybe back to NameValueCollection and using one of the techniques mentioned to remove data)
The idea of storing multiple values with the same key is somehow strange. But I think you can retrieve all values using GetValues then remove the one you don't need and put them back using Set and then subsequent Add methods. You can make a separate extension method method for this.
NameValueCollection doesn't really allow to have multiple entries with the same key. It merely concatenates the new values of existing keys into a comma separated list of values (see NameValueCollection.Add.
So there really is just a single value per key. You could conceivably get the value split them on ',' and remove the offending value.
Edit: #ElDog is correct, there is a GetValues method which does this for you so no need to split.
A better option I think would be to use Dictionary<string, IList<int>> or Dictionary<string, ISet<int>> to store the values as discrete erm, values
You may convert it to 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]);
make your own method, it works for me --
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));
}
then call it on list as --
list.Remove(key,value); //Pass the key value...
Perhaps not the best way, but....
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());
You can use the Dictionary collection instead:
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("typeA", 1);
dictionary.Add("typeB", 1);
When you try to insert type: 11 it will throw exception as Key already exists. So you can enter a new key to insert this data.
Refer this Tutorial for further help.
Here is my code:
string[] inputs = new[] {"1:2","5:90","7:12","1:70","29:60"};
//Declare Dictionary
var results = new Dictionary<int, int>();
//Dictionary<int, int> results = new Dictionary<int, int>();
foreach(string pair in inputs)
{
string[] split = pair.Split(':');
int key = int.Parse(split[0]);
int value = int.Parse(split[1]);
//Check for duplicate of the current ID being checked
if (results.ContainsKey(key))
{
//If the current ID being checked is already in the Dictionary the Qty will be added
//Dictionary gets Key=key and the Value=value; A new Key and Value is inserted inside the Dictionary
results[key] = results[key] + value;
}
else
{
//if No duplicate is found just add the ID and Qty inside the Dictionary
results[key] = value;
//results.Add(key,value);
}
}
var outputs = new List<string>();
foreach(var kvp in results)
{
outputs.Add(string.Format("{0}:{1}", kvp.Key, kvp.Value));
}
// Turn this back into an array
string[] final = outputs.ToArray();
foreach(string s in final)
{
Console.WriteLine(s);
}
Console.ReadKey();
I want to know if the difference if there is between assigning a key=>value pair in a dictionary.
Method1:
results[key] = value;
Method2:
results.Add(key,value);
In method 1, the function Add() was not called but instead the Dictionary named 'results' assigns somehow sets a Key-Value pair by stating code in method1, I assume that it somehow adds the key and value inside the dictionary automatically without Add() being called.
I'm asking this because I'm currently a student and I'm studying C# right now.
Sir/Ma'am, your answers would be of great help and be very much appreciated. Thank you++
The Dictionary<TKey, TValue> indexer's set method (the one that is called when you do results[key] = value;) looks like:
set
{
this.Insert(key, value, false);
}
The Add method looks like:
public void Add(TKey key, TValue value)
{
this.Insert(key, value, true);
}
The only difference being if the third parameter is true, it'll throw an exception if the key already exists.
Side note: A decompiler is the .NET developers second best friend (the first of course being the debugger). This answer came from opening mscorlib in ILSpy.
If the key exists in 1) the value is overwritten. But in 2) it would throw an exception as keys need to be unique