How to access Dictionary in for loop in C# [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have declare a dictionary in C#. But I can't access it by foreach.
Dictionary<int,string>dic=new Dictionary<int,string>()
{
{78,"A"},
{81,"B"},
{90, "C"}
}
Now I want to compare its integer value with an other variable(count). If matches then it will give corresponding string value. How can I access the dictionary by for loop??
I have tried like this.
foreach(int p in dic.Value)
{
if(dic.ContainsKey(p)==count)
{
Console.WriteLine(dic.Values(p));
}
}
It's not working. Not finding anything in any site. Help in advance.

I'm unsure what you are actually trying to ask here. However, below is how to loop over the key value pairs of a dictionary using a foreach.
var dic = new Dictionary<int, string>
{
{78, "A"},
{81, "B"},
{90, "C"}
};
//To loop over the key value pairs of a dictionary
foreach (var keyValue in dic)
{
Console.WriteLine("This is the key: {0}",keyValue.Key);
Console.WriteLine("This is the value: {0}", keyValue.Value);
}
However, i think this is what you are looking to do which requires no loop to find if the key is contained in the dictionary.
const int count = 78;
if (dic.ContainsKey(count))
{
Console.WriteLine(dic[count]);
}
else
{
Console.WriteLine("The dictionary does not contain the key: {0}", count);
}
As #john has mentioned in the comments, you can also use Dictionary.TryGetValue to get the value with a specified key as well
string value;
var success = dic.TryGetValue(count, out value);
if (success)
Console.WriteLine("The dictionary value is: {0}", value);

You can iterate using foreach this way:
foreach(KeyValuePair<int, string> pair in dic)
{
if(pair.Key==count)
Console.WriteLine(pair.Value);
}

Try the example.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> dictionary =
new Dictionary<string, int>();
dictionary.Add("apple", 1);
dictionary.Add("windows", 5);
// See whether Dictionary contains this string.
if (dictionary.ContainsKey("apple"))
{
int value = dictionary["apple"];
Console.WriteLine(value);
}
// See whether it contains this string.
if (!dictionary.ContainsKey("acorn"))
{
Console.WriteLine(false);
}
}
}

Related

How to check more than one value from dictionary in an if statement? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 months ago.
Improve this question
Im just starting to learn unity and saw this task in one of my c# studying books. I have to create a code using an if statement inside foreach, so that it checks if i can afford each item in the dictionary, but i have no idea how to check all of them or even once specific, so i could write if 3 times for example.
At the moment my Log shows all the items and thier values, but shows if i can afford only the first one. What should i put in the IF brackets to check every value after it appears it Log?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LearningCurve : MonoBehaviour
{
public int currentGold = 3;
void Start()
{
Dictionary<string, int> itemInventory = new Dictionary<string, int>()
{
{"Potions", 4 },
{"Daggers", 3 },
{"Lockpicks", 1 }
};
foreach (KeyValuePair<string, int> itemCost in itemInventory)
{
Debug.LogFormat("Item {0} - {1}g", itemCost.Key, itemCost.Value);
if (currentGold >= itemCost.Value)
{
Debug.Log("I can afford that!");
}
}
}
I am not sure if I understood the question but I will try to give you a basic overview of what is happening in the code you posted.
Let's start with the if, how an if block works is simple you put a boolean bool for short in C# that can have two different values true and a false, inside the if(BOOL VALUE) and if the value is true it will run the code between the { CODE TO RUN }.
Let's refactor the code a bit to see what is going on here.
Dictionary<string, int> itemInventory = new Dictionary<string, int>()
{
{"Potions", 4 },
{"Daggers", 3 },
{"Lockpicks", 1 }
};
foreach (KeyValuePair<string, int> itemCost in itemInventory)
{
Debug.LogFormat("Item {0} - {1}g", itemCost.Key, itemCost.Value);
bool iCanBuyitem = currentGold >= itemCost.Value;
Debug.LogFormat("{0} >= {1} is {2}", currentGold, itemCost.Value,iCanBuyitem);
if (iCanBuyitem)
{
Debug.LogFormat("I can buy {0} ", itemCost.Key);
}else
{
Debug.LogFormat("I can't buy {0} ", itemCost.Key);
}
}
Unlike in mathematics in programing symbol >= is not an equality symbol but something called a binary operator that takes two variables of one of the many numeric types in c# in your dictionary they are integers Dictionary<string, int> and produce a bool value that tells you if one number is more or equal to a second number, it's a method that has something similar to the the following signature public bool FirstIsBiggerOrEqualToSecond(int first, int second)
Here is a dotnet fiddle demonstrating the output https://dotnetfiddle.net/oWlYlY
Read the question header You mean, if you want to put two or more conditions inside the IF, you have to use && operator:
if (currentGold >= itemCost.Value && currentGold <= 15)
{
Debug.Log("I have enough gold to buy this item and it's cheap.");
}
Testing the code snippet provided two logs within the Console: "I can afford that!". Through this, I have determined that the issue lies within your snippet implementation. I suggest you check if you have enabled Collapse within the Console.
I have attached an Imgur link for reference.
Console Log

Handle Collision using Hashtable Class in c#

In the below scenario how can I handle or implement collision in C# using the Hashtable class? If the 'Key' value is same I am getting an "Argument Exception".
static void Main(string[] args)
{
Console.Write("Enter a string:");
string input = Console.ReadLine();
checkString(input);
Console.ReadLine();
}
static void checkString(string input)
{
Hashtable hashTbl = new Hashtable();
foreach(char c in input)
{
hashTbl.Add(c.GetHashCode(), c);
}
printHash(hashTbl);
}
static void printHash(Hashtable hash)
{
foreach(int key in hash.Keys)
{
Console.WriteLine("Key: {0} Value: {1}",key,hash[key]);
}
}
My Expectation:
What do I need to do in the 'Value' argument to get around the 'Collision' issue. I am trying to check if the string consists of unique characters.
It seems you are misunderstanding how the Hashtable class works (and it has been deprecated since 2005 - use Dictionary<K,V> instead, but its behavior here is identical).
It seems you're expecting it to be your job to get an object's hashcode and add it to the hashtable. It isn't. All you need to do is add the object you want to use as key (each character), and the internal implementation will extract the hashcode.
However, what you're actually doing won't work even if you added the key object yourself. You're taking an input string (say, "test"), and for each character, you're adding it to the hashtable as a key. But since keys are, by definition, unique, you'll be adding the character 't' twice (it shows up twice in the input), so you'll get an exception.
I am trying to check if the string consists of unique characters.
Then you need keys only without values, that's what HashSet<T> is for.
var chars = new HashSet<char>();
foreach (char c in input)
{
if (chars.Contains(c))
{
// c is not unique
}
else
{
chars.Add(c);
}
}
But I'd prefer usin LINQ in this case:
var hasUniqueChars = input.Length == input.Distinct().Count();
As previously stated you should probably switch to the Dictionary<TKey, TValue> class for this.
If you want to get around the collission issue, then you have to check the key for existence.
Dictionary<string, object> dictValues = new Dictionary<string, object>();
Then you can use check for collission:
if (dictValues.ContainsKey(YourKey))
{
/* ... your collission handling here ... */
}
else
{
// No collission
}
Another possibility would be, if you are not interested in preserving previous values for the same key:
dictValues[YourKey] = YourValue;
This will add the key entry if it is not there already. If it is, it will overwrite its value with the given input.

TryGetValue returns false even though the key exists [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a model class called UnicodeMap that I use to represent the hexadecimal unicode value and its consonants and values for Amharic characters.
public sealed class UnicodeMap
{
public string Letter;
public string Consonant;
public string Vowel;
}
I have stored the mapping in CSV and read in runtime to populate a dictionary.
Here is the excerpt of the code that reads and populates the dictionary:
private Dictionary<string, UnicodeMap> _unicodeMap;
void ReadMap()
{
var engine = new FileHelperAsyncEngine<UnicodeMap>();
using (engine.BeginReadFile(MapFile))
{
foreach (var record in engine)
{
_unicodeMap.Add(record.Letter, record);
}
}
}
When I try to get a value from the dictionary using TryGetValue, it always returns false:
public void Translate(string text)
{
var words = text.Split(' ', '.');
foreach (var word in words)
{
var chr = Char.Parse(word);
var unicodeStr = #"\u" + ((int) chr).ToString("X4");
UnicodeMap map;
if (_unicodeMap.TryGetValue(unicodeStr, out map)) //returns false
{
_animator.SetTrigger(map.Consonant);
_animator.SetTrigger(map.Vowel);
};
}
}
For example, when the string is "ሀ", the value of the unicodeStr variable is "\u1200". And I have a string with the value "\u1200" as a key in the dictionary. However, TryGetValue cannot seem to find the key in the dictionary.
How can I solve this issue? What is the possible cause?
Edit: Added a gif of the debugger looking at the values of _unicodeMap dictionary
It's a little hard to see in the gif, but it appears you have a trailing space after the text in the dictionary keys, so you are actually comparing "\u1200" and "\u1200 ".
Fix the way you populate the dictionary by doing a .Trim() on the key.
private Dictionary<string, UnicodeMap> _unicodeMap;
void ReadMap()
{
var engine = new FileHelperAsyncEngine<UnicodeMap>();
using (engine.BeginReadFile(MapFile))
{
foreach (var record in engine)
{
_unicodeMap.Add(record.Letter.Trim(), record); //Added .Trim()
}
}
}
Or fix FileHelperAsyncEngine to not leave the trailing space in the Letter property.

Replace a Specific Text From a Text

I'm writing a chat helper tool for a game with a custom library.
I want to change specific variables when player sends the message.
This is my code
static List<string> asciis = new List<string> { "shrug", "omg" };
static List<string> converteds = new List<string> { #"¯\_(ツ)_/¯", #"◕_◕"};
private static void Game_OnInput(GameInputEventArgs args)
{
newtext = args.Input;
foreach (var ascii in asciis)
{
foreach (var converted in converteds)
{
if (args.Input.Contains(ascii))
{
newtext = args.Input.Replace(ascii, converted);
Game.Say(newtext);
}
}
}
}
As you can see I'm trying to get the texts from "asciis" and convert them to "converteds" (in order).
Whenever I type something that not in "asciis" list it perfectly works. But whenever I type shrug it prints ¯\_(ツ)_/¯ + ◕_◕ + ◕_◕ (it prints omg 2 times). Same in omg too.
You probably understand that I'm really beginner. I really didn't understand what is wrong with this code...
It seems that your two lists have the same length (in terms of elements contained) and each element in one list has its replacement in the same position in the other list.
Then you could treat the two lists as two arrays and use a different way to search for the input term and replace it with the substitution text
private static void Game_OnInput(GameInputEventArgs args)
{
newtext = args.Input;
for(int x = 0; x < ascii.Count; x++)
if (args.Input.Contains(ascii[x]))
{
newtext = args.Input.Replace(ascii[x], converted[x]);
Game.Say(newtext);
}
}
While i don't think there is a big improvement, you could also implement the same with a dictionary
static Dictionary<string, string> converter = new Dictionary<string, string>()
{
{"shrug", #"¯\_(ツ)_/¯"},
{"omg", #"◕_◕"}
};
private static void Game_OnInput(GameInputEventArgs args)
{
newtext = args.Input;
foreach(KeyValuePair<string, string> kvp in converter)
if (args.Input.Contains(kvp.Key))
{
newtext = args.Input.Replace(kvp.Key, kvp.Value);
Game.Say(newtext);
}
}
Well, probably is a bit more readable, but still we need traversing the dictionary Keys one by one.
As Daniel pointed out in his comment, this is a good use case for dictionaries.
Have a dictionary that maps the text you want replaced to the stuff you want to be replaced with:
Dictionary<string, string> dict = new Dictionary<string, string>
{
{"shrug", #"¯\_(ツ)_/¯" },
{"omg", "◕_◕" }
}; // etc
Then find all occurrences of the keys from the dictionary and replace them with the corresponding values.
Also why are you using static methods and fields? I may be wrong, but I expect most, if not all of your other methods and fields are static as well. I strongly recommend avoiding getting used to them. Try learning more about OOP instead.
Your main problem is that you are always replacing on args.Input, but storing the results in newtext each time, overwriting your previous replacements. Your next problem is that you are outputting the result after each replacement attempt so that's why you are getting multiple weird output results.
I also suggest a dictionary since by definition, it is a mapping of one thing to another. Also, note my changes below, I have moved the Game.Say call outside of the loops and changed "args.Input.Replace" to "newtext.Replace"
Dictionary<string, string> dictionary = new Dictionary<string, string>
{
{"shrug", #"¯\_(ツ)_/¯" },
{"omg", "◕_◕" }
};
private static void Game_OnInput(GameInputEventArgs args)
{
string newtext = args.Input;
foreach(string key in dictionary.Keys){
newtext = newtext.Replace(key,dictionary[key]);
}
Game.Say(newtext);
}

Show C# Array on user request [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I need a way to get the response from a user.
For example they type "hat" and it displays the price in the array table in a console writeline. It also needs to be done in a 2d array instead of dictionary
class Table
{
string[,] names = {
{"rice", "50"},
{"chip", "20"},
{"hat", "50"},
{"ball", "34"},
};
}
class Program
{
static void Main(string[] args)
{
string Res;
Console.WriteLine("What product would you like?");
Res = Console.ReadLine();
Console.ReadKey();
}
}
Use a Dictionary<string, string> rather that way you can look up the Value based on the Key
Dictionary<string, string> example = new Dictionary<string, string>();
example.Add("hat", "50");
//Add the rest in this manner
The you can do the lookup like this
if (example.ContainsKey(Res))
string price = example[Res];
Straightforward solution with 2-d array:
class Program
{
static void Main(string[] args)
{
var products = new[,] { {"rice", "50"}, {"chip", "20"}, {"hat", "50"}, {"ball", "34"} };
Console.WriteLine("What product would you like?");
var request = Console.ReadLine();
string value = null;
if (request != null)
{
for (int i = 0; i < products.GetUpperBound(0); i++)
{
if (products[i, 0] == request)
{
value = products[i, 1];
break;
}
}
}
if (!string.IsNullOrEmpty(value))
{
Console.WriteLine("You've selected: " + request + ". Value is: " + value);
}
else
{
Console.WriteLine("You've selected: " + request + ". No value found.");
}
Console.ReadKey();
}
}
you should be using a Dictionary instead of your jagged array. It is better and you get more flexibility.
var items = new Dictionary<string, string>(5);
items.Add("rice", "50");
items.Add("chip", "20");
// and so on
then you get the item by checking to see if the key exists first:
if (items.ContainsKey("rice"))
{
// it exists! read it:
Console.WriteLine(items["rice"]);
}

Categories

Resources