Check if the number is contained within Dictionary array C# - 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

Related

How to import Dictionary text file and check for word matches?

I generate a random string of 500 characters and want to check for words.
bliduuwfhbgphwhsyzjnlfyizbjfeeepsbpgplpbhaegyepqcjhhotovnzdtlracxrwggbcmjiglasjvmscvxwazmutqiwppzcjhijjbguxfnduuphhsoffaqwtmhmensqmyicnciaoczumjzyaaowbtwjqlpxuuqknxqvmnueknqcbvkkmildyvosczlbnlgumohosemnfkmndtiubfkminlriytmbtrzhwqmovrivxxojbpirqahatmydqgulammsnfgcvgfncqkpxhgikulsjynjrjypxwvlkvwvigvjvuydbjfizmbfbtjprxkmiqpfuyebllzezbxozkiidpplvqkqlgdlvjbfeticedwomxgawuphocisaejeonqehoipzsjgbfdatbzykkurrwwtajeajeornrhyoqadljfjyizzfluetynlrpoqojxxqmmbuaktjqghqmusjfvxkkyoewgyckpbmismwyfebaucsfueuwgio
I import a Dictionary Words txt file and check the string to see if it contains each word. If a match is found, it's added to a list.
I read using Dictionary<> is faster than Array for a words list.
When I use that method, I can see the cpu working the foreach loop in the debugger, and my loop counter goes up, about 10,000+ times in 10 seconds, but the loop continues on forever and does not return any results.
When I use Array for Dictionary, the program works, but slower at around 500 times in 10 seconds.
Not Working
Using Dictionary<>
// Random Message
public string message = Random(500);
// Dictionary Words Reference
public Dictionary<string, string> dictionary = new Dictionary<string, string>();
// Matches Found
public static List<string> matches = new List<string>();
public MainWindow()
{
InitializeComponent();
// Import Dictionary File
dictionary = File
.ReadLines(#"C:\dictionary.txt")
.Select((v, i) => new { Index = i, Value = v })
.GroupBy(p => p.Index / 2)
.ToDictionary(g => g.First().Value, g => g.Last().Value);
// If Message Contains word, add to Matches List
foreach (KeyValuePair<string, string> entry in dictionary)
{
if (message.Contains(entry.Value))
{
matches.Add(entry.Value);
}
}
}
Working
Using Array
// Random Message
public string message = Random(500);
// Dictionary Words Reference
public string[] dictionary = File.ReadAllLines(#"C:\dictionary.txt");
// Matches Found
public List<string> matches = new List<string>();
public MainWindow()
{
InitializeComponent();
// If Message Contains word, add to Matches List
foreach (var entry in dictionary)
{
if (message.Contains(entry))
{
matches.Add(entry);
}
}
}
I doubt if you want Dictionary<string, string> as a dictionary ;) HashSet<string> will be enough:
using System.Linq;
...
string source = "bliduuwfhbgphwhsyzjnlfyizbj";
HashSet<string> allWords = new HashSet<string>(File
.ReadLines(#"C:\dictionary.txt")
.Select(line => line.Trim())
.Where(line => !string.IsNullOrEmpty(line)), StringComparer.OrdinalIgnoreCase);
int shortestWord = allWords.Min(word => word.Length);
int longestWord = allWords.Max(word => word.Length);
// If you want duplicates, change HashSet<string> to List<string>
HashSet<string> wordsFound = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
for (int length = shortestWord; length <= longestWord; ++length) {
for (int position = 0; position <= source.Length - length; ++position) {
string extract = source.Substring(position, length);
if (allWords.Contains(extract))
wordsFound.Add(extract);
}
}
Test: for
https://raw.githubusercontent.com/dolph/dictionary/master/popular.txt
dictionary donwloaded as C:\dictionary.txt file
Console.WriteLine(string.Join(", ", wordsFound.OrderBy(x => x)));
we have output
id, li, lid
Using a Dictionary in this scenario doesn't make much sense. A Dictionary is, essentially, a list of variables that stores both the variable name and the variable value.
I could have the following:
int age = 21;
int money = 21343;
int distance = 10;
int year = 2017;
And convert it to a Dictionary instead, using the following:
Dictionary<string, int> numbers = new Dictionary<string, int>()
{
{ "age", 21 },
{ "money", 21343},
{ "distance", 10 },
{ "year", 2017 }
};
And then I can access a value in the dictionary using its key (the first value). So, for example, if I want to know what "age" is, I would use:
Console.Log(numbers["age"]);
This is only a single example of the power of dictionaries - there is a LOT more that they can do, and they can make your life a lot easier. In this scenario, however, they aren't going to do what you're expecting them to do. I would suggest just using the Array, or a List.
You are misusing the dictionary,
you are basically using the dictionary as a list, so it only added some overhead to the program. not helping in any way.
It would have been useful if you had something you want to query against the dictionary not the other way around.
Also, in any case, what you want is a HashSet, not a dictionary since your key in the dictionary is not the word you are querying against but an irrelevant int.
you can read more about dictionary and HashSet here:
dictionary: https://www.dotnetperls.com/dictionary
hashset: https://www.dotnetperls.com/hashset

how to add data to enum in c# wpf

OK so I have a list which contains few string data set,
i want to assign this list values to enum according ling
my code below
namespace ILS.VM.Config
{
public class loadPortDetails
{
public void Ports()
{
List<string> portnameLIST= new List<string>();
portnameLIST.add(31);
portnameLIST.add(25);
portnameLIST.add(66);
//BaudRate.Baud_11001 = ;
}
}
public enum BaudRate
{
Baud_FLOOR1,
Baud_FLOOR2,
Baud_FLOOR3,
Baud_NONE = 0
};
}
data in the list has to be given as a values to the enum
for example:
Baud_FLOOR1=should have the values from portlist (portnamelist[1])
Baud_FLOOR2=should have the values from portlist (portnamelist[2])
You can't add/change the enum value in runtime
If you need a key-value pairs, I suggest to use Dictionary
Update:
So if you need to store int FloorNumber -> string PortNumber relationship
you should create a dictionary
Dictionary<int, string> floorPortMap = new Dictionary<int, string>();
To add pair you should use Add method.
floorPortMap.Add(10, "777"); // adds the (10, "777") pair to the dictionary.
To update pair you should use [] operator like
floorPortMap[10] = "8888" // changes previous (10, "777") pair to (10, "888")
Note that unless the value is specifically assigned the first enum will have the value 0, so in your code both Baud_FLOOR1 and Baud_NONE would have the value 0.
If the values will not change at runtime - you can assign values like this :
public enum BaudRate
{
Baud_NONE, // assignment of zero to first enum not required
Baud_FLOOR1 = 31,
Baud_FLOOR2 = 25,
Baud_FLOOR3 = 66
};

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.

Removing blank space from the dictionary key name

I have a Dictionary with some key-value pairs stored in it. My problem is that in my dictionary, I have a blank space at the start of the key name, so for accessing the value, I have to use:
Pair[" Key"];
Is there any method where I can remove the starting whitespace, so I can access the value like:
Pair["Key"]
If you have a string, you can remove leading and trailing whitespace with key.Trim() (MSDN).
If you want to trim all the keys in your dictionary, you can do this:
dictionary = dictionary.ToDictionary(x => x.Key.Trim(), x => x.Value);
This has room for failure, though, if you have 2 keys that will trim to the same value. For example, it is valid to have a dictionary with keys " key" and "key ", but if you trim them all, you'll get an ArgumentException because you'd be trying to add the same key twice ("key").
Trimming your string is enough. Besides that you can also write a custom key comparer for your dictionary instead of trimming your string everytime you add or get something to/from your dictionary.
Dictionary<string, int> dict = new Dictionary<string, int>(new Comparer());
dict.Add("aa ", 10);
int i = dict[" aa"];
public class Comparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return x.Trim().Equals(y.Trim());
}
public int GetHashCode(string obj)
{
return obj.Trim().GetHashCode();
}
}
Use string.Trim method:
var key = " Key".Trim();
Pair[key];

issue while getting values from Dictionary<int, List<int>>

I am having a dictionary which was defined as follows
Dictionary<int, List<int>> dict1 = new Dictionary<int, List<int>>();
I will have a list element where i can store the values which will come from database
List<int> lstdbTaskID = new List<int>();
assume this holds
100 105 110 200
respectively.
I will have my dictionary with values stored as follows. Assume that i have 2 keys 10,20 respectively, and for this key values i will have my values as for 10 i will have 100,105 and 110 and for 20 i will have 200.
I would like to compare these values with the list available lstdbTaskID
I tried this
foreach (int strlst in lstdbTaskID)
{
if (dict1.ContainsValue(lstdbTaskID[strlst]))
}
But i am getting errors as follows
The best overloaded method match for 'System.Collections.Generic.Dictionary>.ContainsValue(System.Collections.Generic.List)' has some invalid arguments`
and
Cannot convert from 'int' to 'System.Collections.Generic.List'`
can any help me on this?
Your code is wrong at because you are trying to compare int value with List of int.
Your dictionary is:
Dictionary of int to List of int.
and you have another structure as
List of int
so when you do:
// Compiler fails here because you are trying to check whether dictionary contains
// the given integer value. Dictionary in this case has a list of integers as its `Value`
// in its `<Key,Value>` pair.
dict1.ContainsValue(lstdbTaskID[strlst])
Use linq statement:
foreach (int strlst in lstdbTaskID)
{
if (dict1.Any(pair => pair.Value.Contains(strlst)))
{
// do something
}
}
Edit: If you want this without linq, do the linq task by self.
foreach (int strlst in lstdbTaskID)
{
foreach (int key in dict1.Keys)
{
if (dict1[key].Contains(strlst))
{
// do something
}
}
}
Look at the type of the value you're storing in your dictionary - it's a List<int>, not an int. So it makes no sense to ask whether the dictionary contains a value of 5, say.
However, it does make sense to ask if the dictionary contains any value (list) which itself contains 5.
For example:
foreach (int strlst in lstdbTaskID)
{
if (dict1.Values.Any(list => list.Contains(strlst))
{
...
}
}
However, that's really not a very efficient way of representing it. It's not clear what the best of representing it is though, without knowing what you're going to do with the results. You may just want a HashSet<int> containing all the values from all the lists, for example - but if you want to get back to the keys whose values contained a particular ID, that's a different matter.
EDIT: In .NET 2.0 land, you could use:
foreach (int strlst in lstdbTaskID)
{
foreach (List<int> list in dict1.Values)
{
if (list.Contains(strlst))
}
}
... but you're really not using the dictionary as a dictionary in either case here...
I am having slight problems understanding your question fully, however, my answer should push you in the right direction. Seeing as you do not have access to Linq (as you are using .Net 2.0):
static bool IsContained(IEnumerable<int> lstdbTaskID, Dictionary<int, HashSet<int>> dict1)
{
foreach (int strlst in lstdbTaskID)
foreach (HashSet<int> value in dict1.Values)
if (value != null && value.Contains(strlst))
return true;
return false;
}
You should use a HashSet<int> as it is far faster for looking up values (and is supported in .Net 2.0); however, you should not use HashSet<int> (and instead use List<int>) if:
The list needs to store duplicates.
- or - The order of the values is important.
Well, dict1 is a dictionary of dictionaries, not ints. So dict1.ContainsValue takes a dictionary as a parameter - you're checking whether it contains a given dictionary or not. But you're giving it an int.
Try this:
if (dict1.Any(x => x.Value.ContainsValue(strlst))) // ...

Categories

Resources