C#: Set integer for any given string - c#

I want to list the cost for every of my Upgrades.
Example:
String:"Faster Shooting",int: 10
I want an easy way to set a specific int for any string from a long list and later get the int, by the string

Use a Dictionary<TKey,TValue>, which is a collection of key-value pairs. In this case, your key would be a string and your value an int:
var dict = new Dictionary<string, int>();
dict["Faster Shooting"] = 10; // add "Faster Shooting" key, set to value 10.
dict["Faster Shooting"] = 15; // update "Faster Shooting" key, set to value 15.
Console.WriteLine(dict["Faster Shooting"]); // print "Faster Shooting" value
It also exposes Add(), TryAdd(), and other convenient methods, see #Heinzi's answer for an alternative using Add().

I want an easy way to set a specific X for any Y from a long list and later get the X, by the Y.
There's a built-in .NET data structure for exactly this purpose: A dictionary (sometimes called map, hash map or associative array in other programming languages).
Code example:
var dic = new Dictionary<string, int>();
dic.Add("Foo", 3);
dic.Add("Bar", 4);
Console.WriteLine(dic["Foo"]); // prints 3
Further examples can be found in the documentation.

Related

Dictionary Unhandled Exception in C#: "The given key was not present in the dictionary"

I'm trying to print out a dictionary in C# that will simulate a graph. My dictionary looks like this:
Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
In main, I add something to the dictionary, then try to print it out:
dicOfLists myDic = new dicOfLists();
myDic.AddEdge(1, 2);
myDic.printList();
The methods AddEdge and PrintList are pretty straightforward:
AddEdge:
public void AddEdge(int v1, int v2)
{
if (graph[v1] == null)
{
graph[v1] = new List<int> { v2 };
return;
}
graph[v1].Add(v2);
}
PrintList:
for (int i = 0; i < 1; i++)
{
Console.WriteLine(graph[i][i]);
}
I haven't done much programming in C# or Python, so dictionaries are new to me. I think why I'm getting tripped up is more conceptual than anything, specifically because I'm not sure how a list works within a dictionary.
The way I currently understand it is as follows:
Upon calling Addedge(1, 2) my dictionary is creating a list with a single element 2 at position 1 of my dictionary. This is because the first parameter represents the dictionary's key, and the second represents the list. The key functions like it would in a hashtable. When the key is provided, the dictionary looks at that position, and then creates a list.
Like I said, I'm new to C# so please don't skewer me too hard. While this might be something trivial like a straightforward syntax error, I'm not able to find much of anything for this specific problem online. Any help would be greatly appreciated!
You've got one method adding key/values to a dictionary and another printing them. The method printing them doesn't "know" what's been inserted, so it's better if that method doesn't make any assumptions about what's in the dictionary. Instead of just looping through a series of possible keys (0 to 1, 0 to n, etc.) it's better to operate according to what actually is in the dictionary.
var keys = graph.Keys;
// or, if you they were entered out of sequence and you want to sort them
var keys = graph.Keys.OrderBy(k => k);
// Now you're using the actual keys that are in the dictionary, so you'll never
// try to access a missing key.
foreach(var key in keys)
{
// It's not quite as clear to me what you're doing with these objects.
// Suppose you wanted to print out everything:
Console.WriteLine($"Key: {key}");
foreach(var value in graph[key])
{
Console.WriteLine(value);
}
}

Check if the number is contained within Dictionary array C#

I have Dictionary that the key is an array of int, and the value is a string. How can I get the value by check if int is contained in the key array?
public static Dictionary<int[], string> MyDic = new Dictionary<int[], string>
{
{new int[]{2,25},"firstValue"},
{new int[]{3,91,315,322},"secondValue"}
};
I have :
int number=91;
string value=?;
I need the value will get "secondValue"
I think this is a bad design choice. If the numbers don't repeat between keys (as you said in your comment for the question) then just flatten the keys into a simple Dictionary<int,string>. Just have the different integers all be keys for the same strings.
For example:
Dictionary<int,string>
{
[2] = "firstValue",
[25] = "firstValue",
};
In order to not repeat the same values but as different objects you can place a reference there:
string firstValue = "firstValue";
Dictionary<int,string>
{
[2] = firstValue,
[25] = firstValue,
};
In this case changing the value's content (not for a string as it is immutable but if it was some other object) for one key will change for all.
Use contains and a foreach loop (more readable than some other solutions):
string value;
int number = 91;
foreach(KeyValuePair<int[], string> entry in MyDic)
{
if (entry.Key.Contains(number))
{
value = entry.Value;
}
}
However, maybe a dictionary isn't the right choice for this.
Check out Gilads answer for another structure that you could use
string value = MyDic.FirstOrDefault(x => x.Key.Contains(number)).Value;
? is not needed, can not apply ? operand to KeyValuePair
something like
value = MyDic.FirstOrDefault(x => x.Key.Contains(number)).Value;
will return the first occurrence or null

How to keep track of 2 related values and add new as needed?

I have a situation where I am translating a file, and if I encounter a string of "#sometext" versus "#45" where I would use the value of 45, I need to start correlating that value as (#sometext,16) and each time I encounter "#sometext" translate it as 16, but if I then later encounter "#othertext" I would use the next incremented value (17) each time it is referenced.
Is there a simple way in C# for me to handle this type of operation? Each time I enounter "#text" check all entries for that text, and if not found, add it as an entry with the next incremented reference value?
I thought a 2D array might work, but I'm not thinking I'll be able to easily search current entries to see if text exists already.
Use a Dictionary.
Dictionary<string, int> textDict = new Dictionary<string, int>();
int initial = 16;
...
public string ReplaceText(string stringVal)
{
if (!textDict.ContainsKey(stringVal))
textDict.Add(stringVal, initial + textDict.Count);
return textDict[stringVal].ToString();
}

swapping two key/value pairs in Dictionary of C#

here is what I want to do.
there is a Dictionary having 54 key/value objects. I want the key/value pair at index i to be swapped with the key/value pair at index j...
int i=1; int j=3;
Dictionary<String, int> theDeck = new Dictionary<String, int>();
theDeck.Add("zero", 0);
theDeck.Add("one", 1);
theDeck.Add("two", 2);
theDeck.Add("three", 3);
KeyValuePair<String, int> p1 = theDeck.ElementAt(i);
KeyValuePair<String, int> p2 = theDeck.ElementAt(j);
theDeck.ElementAt(i) = p2; //THIS LINE DOES NOT WORK. WHAT IS ITS ALTERNATIVE
theDeck.ElementAt(j) = p1; //THIS LINE DOES NOT WORK. WHAT IS ITS ALTERNATIVE
Dictionary<,> instances don't have "indexes" - you shouldn't treat them as ordered at all. Any order you may happen to notice when iterating over entries should be seen as an implementation detail.
If you want a specific order, there are various different types you could use, depending on your requirements. For example, to sort based on the key you'd use SortedDictionary<,> or SortedList<,>. For arbitrary ordering, consider OrderedDictionary (which is unfortunately non-generic).
Do you definitely need a dictionary at all? Could you just use a List<KeyValuePair<string, int>> or perhaps a List<Card> where Card is a custom type? (I'm guessing at your use case - Card could be any type which represents everything in your entry.)
Make mirroring (the 2nd) dictionary, and use it as a key source. Combine in 3d dictionary, while processing.
Try this.This worked for me.
First convert dictionary to list then find indexes of objects to be swapped.After swapping convert list back to dictionary.
var list = someDictionary.ToList();
int indexA = list.FindIndex(objA=> (condition));
int indexB = list.FindIndex(objB => (condition));
list.SwapListEntries(indexA, indexB);
someDictionary=list.ToDictionary(obj => obj.Key, obj => obj.Value);

How can I replace int values in a dictionary C#

I am wondering how I could replace int values in a dictionary in C#.
The values would look something like this.
25,12
24,35
12,34
34,12
I was wondering how I could only replace one line. For example if I wanted to replace the first line with a new value of 12,12. And it wouldn't replace any of the other '12' values in the dictionary.
A Dictionary<TInt, TValue> makes use of what are known as indexers. In this case, these are used to access elements in the dictionary by key, hence:
dict[25] would return 12.
Now, according to what you want to do is to have a key of 12 and a value of 12. Unfortunately, you cannot replace entries in a dictionary by key, so what you must do is:
if(dict.ContainsKey(25))
{
dict.Remove(25);
}
if(!dict.ContainsKey(12))
{
dict.Add(12, 12);
}
Note: In the values you supplied, there is already a key-value pair with 12 as its key, so you would not be allowed to add 12,12 to the dictionary as if(!dict.ContainsKey(12)) would return false.
You cannot replace the first line with 12, 12 because there is another key value pair with 12 as it's key. And you cannot have duplicate keys in a dictionary.
Anyway you may do such things like this:
Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(25, 12);
myDictionary.Add(24, 35);
//remove the old item
myDictionary.Remove(25);
//add the new item
myDictionary.Add(12, 12);
EDIT: if you are going to save some x,y positions I would suggest you creating a class named Point and use a List<Point>. Here is the code:
class Point
{
public double X {get; set;}
public double Y {get; set;}
public Point(double x, double y)
{
this.X = x;
this.Y = y;
}
}
Then:
List<Point> myList =new List<Point>();
myList.Add(new Point(25, 13));
In Dictionaries, the keys must be unique.
In case the key need not be unique, you could use a List<Tuple<int, int>> or List<CustomClass> with CustomClass containing two integer fields. Then you may add or replace the way you want.

Categories

Resources