Im new to Dictionaries, so i have this basic question.
I have a dictionary like this:
Dictionary<string, string> usersLastStamp = checking.checkLastStamp();
How can i do a if statement that checks if a value of a specific key is something?
Like this:
if(usersLastStamp.the_value_of_key("theKey") == "someValue")
{
//Do something
}
I've taken a look at TryGetValue, but im not quite sure how to use it directly like the above in a if statement.
usersLastStamp["theKey"] will throw an exception if the key is not present in the dictionary (as specified here). You can use TryGetValue instead and combine it with short circuit evaluation:
string value = null;
if (usersLastStamp.TryGetValue("theKey", out value) && (value == "someValue"))
{
}
Folks have already answered the TryGetValue approach, but as an alternative: if it is an option, you could also consider using StringDictionary instead of Dictionary<string,string> - this returns null in the case that there is no value at that key, so you can just use:
if(usersLastStamp["theKey"] == "someValue")
without any risk of it erroring.
You could try
if(usersLastStamp["theKey"] != null && usersLastStamp["theKey"] == "SomeValue")
{
// Your cdoe writes here
}
You can use either
string someVal = "";
if (myDict.ContainsKey(someKey))
someVal = myDict[someKey];
or
string someVal = "";
if (myDict.TryGetValue(somekey, out someVal))
and then your if:
if (someVal == "someValue")
TryGetValue takes an out parameter, returns a bool, retruns true and updates the parameter if the key exists in the dictionary, if key doesn't exist in the dictionary returns false. Or you have to check if the key exists in the dictionary and only if it exists then take the value from it.
Related
I am trying to implement a dictionary in such a way that It will only add in a certain value to a key if that new value is greater than the currently existing value
So the basic scenarios would be:
If the key is not available, it will create a new key and a value
If the key if available, it will check if the current value is greater than the value that is already assigned to that key and will only update if it is greater.
Before I explain the problem I am facing here is my code
static IDictionary<string, string> versionStack = new Dictionary<string, string>();
foreach(var item in RequiredApps)
{
nameOfApp = item.Key;
minimumVersionOfApp = item.Value.minVersion;
if (versionStack.TryGetValue(nameOfApp, out minimumVersionOfApp))
{
if (Convert.ToInt32(minimumVersionOfApp) >= Convert.ToInt32(item.Value.minVersion))
minimumVersionOfApp = item.Value.minVersion;
}
versionStack[nameOfApp] = minimumVersionOfApp;
}
Note: Kindly do not worry about the for loop as it works fine and gives no problem there. Just want to display only the specific code that gives me problem
Right now I have been able to fulfill the functionality to a certain level but the problem is when the TryGetValue is executed it turns all my values to null.
I am using the TryGetValue to see if a key has a value and if so to retrieve it.
I am stuck here right now and would appreciate if anyone can help show me what I am doing wrong.
Edit :-
Given that the problem I am facing is quite unclear and as suggested by Rufus L I am adding a sample dummy application with exactly the problem I am facing
Hope this helps to clear any confusion :)
class Program
{
static IDictionary<string, string> versionStack = new Dictionary<string, string>();
static string appName;
static string minVersion;
static void Main(string[] args)
{
AddOnce();
AddTwice();
}
public static void AddOnce()
{
appName = "app01";
minVersion = "1.0";
versionStack.Add(appName, minVersion);
}
public static void AddTwice()
{
string existingValue;
appName = "app01";
minVersion = "3.0";
if (!versionStack.TryGetValue("app01", out existingValue) || Convert.ToInt32(existingValue) < Convert.ToInt32(minVersion))
{
versionStack[appName] = minVersion;
}
}
}
Based on the code you've shown, it looks like the problem is that you're using minimumVersionOfApp as the out parameter to the TryGetValue method, which will be set to null if TryGetValue fails, but then we're using it anyway.
Remember that the contract with any out parameter is that the method must assign a value to it before it returns. Typically (and specifically in this case), if TryGetValue returns false, then the out parameter is set to the default value for the type, which is null for classes.
Then, after the first if statement, you are assigning the value to the key even when TryGetValue returns false, which is likely why you're getting null values.
Instead, only use the out parameter if TryGetValue succeeds.
Here's a sample code that does this:
foreach(var item in RequiredApps)
{
var appName = item.Key;
string existingValue; // Note that this should be the same type as item.Value
// If the key doesn't exist (the first condition),
// or it does exist and our value is greater than the existing one (second condition)
// then update the key with our new value
if (!dependentModuleStack.TryGetValue(appName, out existingValue) ||
Convert.ToInt32(existingValue) < Convert.ToInt32(item.Value.minVersion))
{
versionStack[appName] = item.Value.minVersion;
}
}
It looks like your issue is not with Dictionary.TryGetValue, but Convert.ToInt32
The version number is a double, and not an integer. you should use the Convert.ToDouble instead of Convert.ToInt32
if (!versionStack.TryGetValue("app01", out existingValue) || Convert.ToDouble(existingValue) < Convert.ToDouble(minVersion))
{
versionStack[appName] = minVersion;
}
I have one ASP.Net MVC - 5 application and I want to check if the session value is null before accessing it. But I am not able to do so.
//Set
System.Web.HttpContext.Current.Session["TenantSessionId"] = user.SessionID;
// Access
int TenantSessionId = (int)System.Web.HttpContext.Current.Session["TenantSessionId"];
I tried many solutions from SO
Attempt
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//The code
}
Kindly guide me.
Error: NULL Reference
if(Session["TenantSessionId"] != null)
{
// cast it and use it
// The code
}
The NullReferenceException comes from trying to cast a null value. In general, you're usually better off using as instead of a direct cast:
var tenantSessionId = Session["TenantSessionId"] as int?;
That will never raise an exception. The value of tenantSessionId will simply be null if the session variable is not set. If you have a default value, you can use the null coalesce operator to ensure there's always some value:
var tenantSessionId = Session["TenantSessionId"] as int? ?? defaultValue;
Then, it will either be the value from the session or the default value, i.e. never null.
You can also just check if the session variable is null directly:
if (Session["TenantSessionId"] != null)
{
// do something with session variable
}
However, you would need to confine all your work with the session variable to be inside this conditional.
[] acts as an indexer (like a method on the class) and in this case, session is null and you cannot perform indexing on it.
Try this..
if(Session != null && Session["TenantSessionId"] != null)
{
// code
}
Check if the session is empty/Null or not in C# MVC Version Lower than 5.
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//cast it and use it
//business logic
}
Check if the session is empty/Null or not in C# MVC Version Above 5.
if(Session["TenantSessionId"] != null)
{
//cast it and use it
//business logic
}
There is a case when you want to check only for existence of the key itself but not the content. Above method fails when you Session key value is null also.
Eg:
Session["myKey"] = null;
if(Session["myKey"]!=null){}
In above code, I want to check if only the key (not value) exists, I will get false. But the key does exists.
So the only way I could separate this existence check, is by basically checking each key.
static bool check_for_session_key(string SessionKey)
{
foreach (var key in HttpContext.Current.Session.Keys)
{
if (key.ToString() == SessionKey) return true;
}
return false;
}
if(check_for_session_key("myKey")){} //checks for the key only
Let me know if you know better way.
Check if the session is empty/Null or not
if (!string.IsNullOrEmpty(Session["TenantSessionId"] as string))
{
//here write code for logic
}
I want to use the value of a dictionary without assigning it to a variable:
Dictionary<int, string> LayoutByID = new Dictionary<int, string>() {
{ 0, "foo"},
{ 1, "bar"}
// ...
};
I can for e.g. print the values if I create a variable:
string b;
LayoutByID.TryGetValue(1,out b);
print("Trying Dictionary to retrieve value for 1: " + b);
But I was wondering if there is a simpler way, something like:
print("Trying Dictionary to retrieve value for 1: " + LayoutByID.TryGetValue(1 [???]));
I understand I could write a function with a switch in it that would work similarly, but using Dictionaries might be cheaper as I have a longer list.
Thanks for advice!
You can access the Dictionary with the key like var x = LayoutByID[0]; But you will get an exception, if the Dictionarydoes not contain an entry with that key.
In order to avoid an exception being throw, you can first check if the key exists using LayoutByID.ContainsKey() - and then write your logic for those cases:
if (LayoutByID.ContainsKey(0)) // Check if the key exists (replace 0 with whatever)
{
var x = LayoutByID[0]; // Access the value and do whatever with it
// ...
}
else
{
// Key doesn't exist:
// Do something else
}
or with C# 6.0 you could also print like this
var key = -1;
var myString = string.Empty;
LayoutByID.TryGetValue(key, out myString);
Console.WriteLine($"Trying Dictionary to retrieve value for {key}: {myString ?? "Error: Invalid ID"}");
You can create your own extension method.
[Extension]
public static string GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue>,
TKey key,
TValue defaultValue)
{
if(this.ContainKey(key) == true) return this[i];
return defaultValue;
}
Then use it
Console.WriteLine("Print value for key 1: " + LayoutByID.GetValueOrDefault(1, ""));)
With extension method you will get more clearer and readable code and can use same logic in other places
int selectingvalue = 1;
print(LayoutByID.ContainsKey(selectingvalue) ? LayoutByID.First(x => x.Key == selectingvalue).Value : "");
The problem you seem to have with not wanting to assign to a variable seems to be that you want to retrieve a Dictionary value in short and concise code without the extra 'noise' of having to check the value exists and prevent an "unhandled null exception".
In this case I would recommend using a null-coalescing operator. It works like this:
x ?? y
If x is null, y will be used. If x is not null, x will be used.
Console.WriteLine($"Trying Dictionary to retrieve value for 1: {LayoutByID[0] ?? "value not found"}")
This way you do not have to do any checks first, and in case of null, you will be defaulted to "value not found".
That said, its probably not the best thing to put a bit of logic inside the Console.WriteLine(). I personally would prefer to do this (although you have said you don't want to assign to a variable first):
var x = LayoutByID[0] ?? "value not found"
Console.WriteLine($"Trying Dictionary to retrieve value for 1: {x}")
In my desktop C# application I start with a dictionary. I want to be able to check this dictionary for a key. If the dictionary has this key, I would like to pass it on to a method. If the dictionary doesn't have this key, I would like to create a blank list and just pass that on instead. How can I do this?
I get the error "given key was not present in the dictionary". Can I add a default so it is never null maybe?
// myDic was declared as a Dictionary<string, List<string>
// Here is how I call someFunction
string text = SomeFunction(stringValue1, stringValue2, myDic[field1.field2]);
// SomeFunction looks like this
string SomeFunction (string string1, string string2, List<string> ra)
{
// method
return stringResult;
}
Updated based on comments. To pass one key that may or may not exist you may do this(assuming the value is a List):
// assuming the method we are calling is defined like this:
// public String SomeFunction(string string1, String string2, List<String> ra)
List<string> valueToPassOn;
if (_ra.ContainsKey(lc.Lc))
{
valueToPassOn = _ra[lc.Lc]
}
else
{
valueToPassOn = new List<string>();
}
string text = tooltip.SomeFunction(something1, something2, valueToPassOn);
Should you want to pass an entire dictionary (as the question originally read), regardless of whether or not the dictionary exists:
You have two options. Either create the dictionary regardless like this:
if (myDic == null)
{
// change var and var2 to the types of variable they should be, ex:
myDic = new Dictionary<string, List<string>>();
}
string text = SomeFunction(stringValue1, stringValue2, myDic);
or, what is probably the better option, in the declaration of the function SomeFunction add a dictionary as a variable with a default parameter. Just be sure that your function knows what to do if the dictionary is null.
string SomeFunction(string string1, string string2, Dictionary dictionary = null)
{
// method here
}
You can check if the key exists using ContainsKey method and if it returns false you can pass a default value you want:
// replace default(string) with the value you want to pass
// if the key doesn't exist
var value = myDic.ContainsKey(field1.field2) ? myDic[field1.field2] : default(string);
string text = SomeFunction(stringValue1, stringValue2, value);
What you need to do is make sure the dictionary actually contains the given key in the dictionary.
If you need to extract the value by key, use TryGetValue method:
string value;
if (myDict.TryGetValue(key, out value))
{
// Key exists in the dictionary, do something with value.
}
Use one of the following snippets in order to check if dictionary is empty and take some action:
var x = new Dictionary<string, string>();
if (x.Any())
{
//....
}
if (x.ContainsKey("my key"))
{
}
if (x.ContainsValue("my value"))
{
}
if (x.Count > 0)
{
}
I've seen a couple examples of how to check if a query string exists in a url with C#:
www.site.com/index?query=yes
if(Request.QueryString["query"]=="yes")
But how would I check a string without a parameter? I just need to see if it exists.
www.site.com/index?query
if(Request.QueryString["query"] != null) //why is this always null?
I know there's probably a simple answer and I'll feel dumb, but I haven't been able to find it yet. Thanks!
If you do not specify a value, the key will be automatically set to null, so you cannot check its existence.
In order to check if the value actually exists, you can check in the collection of Values equalling null if it contains your Key:
Request.QueryString.GetValues(null).Contains("query")
this is the fastest way to check it thanks to Ludovic's answer
if(Request.QueryString.GetValues(null)?.Contains("query")??false)
It returns null because in that query string it has no value for that key. I think the check you're looking for is this:
if(Request.QueryString.Keys.OfType<string>().Any(k => k == "query"))
or even:
if(Request.QueryString.AllKeys.Any(k => k == "query"))
The latter is probably more appropriate because that array is already cached.
If query was included as a parameter, but no value was specified, then the value of query will be null but it will still exist in Request.QueryString.AllKeys.
If query was not included, it won't exist in Request.QueryString.AllKeys at all.
Ludovic has the right answer. But I would like to offer a more robust version.
var valueEntries = Request.QueryString.GetValues((string)null) ?? new string[] {};
if (valueEntries.Contains("query", StringComparer.OrdinalIgnoreCase))
{
// value is specify in querystring
}
else
{
// value is NOT specify in querystring
}
This is verbose and it works. Here is a .NET Fiddle.
#using System.Linq;
#{
var empties = Request.Url.Query
.Split('&')
.Where(s => !s.Contains("=") || s.Last() == '=');
var keyExistsAndIsEmpty = empties.Any(x => x.Contains("target-key")
}
It turns out that if the value is null, then the key is also null in the QueryString collection. Your best bet is simply to assign a value to the query. There might be a way for you to rename the parameter so that this makes more semantic sense. For example instead of www.site.com/index?getdocument=yes you could do www.site.com/index?action=getdocument
However if you still want the url www.site.com/index?query to work, there is a way: don't use the QueryString at all and parse the URL manually:
string query = Request.RawUrl.Split('?')[1];
if (query == "query")
{
// send the data
}
You cannot use a null check to determine if a key exists when the "=" is not supplied since null means that the key wasn't in the query string.
The problem is that "query" is being treated as a value with a null key and not as a key with a null value.
In this case the key is also null inside Request.QueryString.AllKeys.
I used this generic method to "fix" the null key problem in the query string before using it. This doesn't involve manually parsing the string.
Usage example:
var fixedQueryString = GetFixedQueryString(Request.QueryString);
if (fixedQueryString.AllKeys.Contains("query"))
{
}
The method:
public static NameValueCollection GetFixedQueryString(NameValueCollection originalQueryString)
{
var fixedQueryString = new NameValueCollection();
for (var i = 0; i < originalQueryString.AllKeys.Length; i++)
{
var keyName = originalQueryString.AllKeys[i];
if (keyName != null)
{
fixedQueryString.Add(keyName, originalQueryString[keyName]);
}
else
{
foreach (var keyWithoutValue in originalQueryString[i].Split(','))
{
fixedQueryString.Add(keyWithoutValue, null);
}
}
}
return fixedQueryString;
}
I Prefer to use:
If(Request.QueryString.AllKeys.Contains("query")
{
//
}