get string array out of Dictionary<int, string[]> - c#

this is my code
pritvate static Dictionary<int, string[]> _list = new Dictionary<int, string[]>();
how can i get the string[] out of this?
I have tried this and a lot more:
string[] s = _list.Values;
but it is all not working.
please help

If you want all string arrays for all keys merged into a single array, you can use LINQ's .SelectMany(...):
var strings = _list.Values.SelectMany(v => v).ToArray()
Reading your question again, I wonder if you're asking how to access a value for a single key. So, if you want the string array for a single key you can simply use the indexer:
var value = _list["keyname"];
But that will cause an exception if the key doesn't exist. If you're not sure that the key exists, you can use .TryGetValue(...):
string[] value;
if (_list.TryGetValue("keyname", out value))
{
// value was found
}
else
{
// value wasn't found
}

Related

Append a value in dictionary .net

I want to append a string value in my dictionary in .net however I couldn't find an information about it for .net. Here is my dictionary which is set already with key-value pairs:
Dictionary<int, string> mydict = new Dictionary<int, string>();
I want to append new strings into existing ones in values.
For example: If we have <1,A> pair I want to append it to <1,AB>. Does anybody know a way to do this?
Well I am not sure what you trying to do, but let me guess: if you have key which exists, you want to append to the corresponding value, if not, insert new key-value pair? If so, see code bloew:
var key = 1;
var val = "new value to append";
if (myDict.CotainsKey(key))
{
myDict[key] += val;
}
else
{
myDict.Add(key, val);
}

c# dictionary select value from key

I've been searching through here and I realize that similar questions have been asked before, and I've gone over several, but what seems to be correct doesn't seem to be working for.
I have the following method which pulls a set of key value pairs in a DataSet gathered from a SQL query.
public static Dictionary<string, string> LoadConfiguration()
{
DataSet sqlResults = data.GetSettings();
Dictionary<string, string> dict =
new Dictionary<String, String>();
foreach (DataRow dr in sqlResults.Tables[0].Rows)
{
dict.Add(
dr.Field<string>("key"), dr.Field<string>("value")
);
}
return dict;
}
It's as simple as it gets as far as I can see, but I've never actually worked with a dictionary before as I'm relatively new to any kind of real programming.
I know that my Dictionary has the expected data, because if I iterate through it with a foreach, it gives me the expected results
foreach (KeyValuePair<string, string> i in MyStuff.Configuration.LoadConfiguration())
{
Console.WriteLine("Key = " + i.Key + " Value = " + i.Value);
}
which gives me the following which is all I've implemented so far
Key = EnableLdap Value = false
Key = LdapPath Value = LDAP://DC=some,DC=domain,DC=com
Key = SessionTimeout Value = 60
But I only want to select a specific value from a key named EnableLdap for example
My understanding is that both the following methods would be correct. But when I try this way, I get a KeyNotFoundException
Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
Console.WriteLine(dict["EnableLdap"]);
If I try this I get a [InvalidOperationException: Sequence contains no matching element]
Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value);
And if I try this I just get nothing
string value = "";
if (dict.TryGetValue("EnableLdap", out value))
{
dict["EnableLdap"] = value;
Console.WriteLine(value);
}
I'm pretty certain I'm missing something simple here and the answer will result in a facepalm
SOLUTION:
I got caught by trailing spaces as was suggested a few times in the comments. The solution was to simply add some trimming to my row values when adding them to my Dictionary.
public static Dictionary<string, string> LoadConfiguration()
{
DataSet sqlResults = data.GetSettings();
Dictionary<string, string> dict =
new Dictionary<String, String>();
foreach (DataRow dr in sqlResults.Tables[0].Rows)
{
dict.Add(
dr.Field<string>("key").Trim(), dr.Field<string>("value").Trim()
);
}
return dict;
}
It is one of these 2 issues.
The key does not exist in the dictionary, this could be due to a spelling mistake or even a leading/trailing space or something of that nature.
The key exists but is cased differently than you think it is.
For option 2 you can ensure that casing is not an issue by providing a StringComparer to the dictionary as an argument in the constructor.
Dictionary<string, string> dict = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
The above code snippet will ensure that the dictionary creates the hash for each key based on the ordinal case insensitive representation of the string key. This will allow for the following example to pass:
dict["enableldap"] = "true";
Console.WriteLine(dict["EnableLdap"]);
See StringComparer for more options.
My understanding is that both the following methods would be correct. But when I try this way, I get a KeyNotFoundException
It seems that your dictionary doesn't have that key. Keep in mind that dictionaries are key-sensitive you can check if a key exist by using this method:
Console.WriteLine("Exist key "+ dict.ContainsKey("EnableLdap"));
If I try this I get a [InvalidOperationException: Sequence contains no matching element]
Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value);
The linQ method .Single expects to find a value. If no value is found that Exception will be thrown. You should be using .SingleOrDefault if you don't want that exception, but beware of nulls.
And if I try this I just get nothing.
TryGetValue doesn't throw any exceptions. It just tries.
I'd suggest you to add a format for your keys either uppercased or lowercased, when you're creating the dictionary.
foreach (DataRow dr in sqlResults.Tables[0].Rows)
{
dict.Add(
dr.Field<string>("key").ToUpperCase(), dr.Field<string>("value")
);
}
and then you can query it like this:
if(dict.ContainsKey("ENABLELDAP"))
{
string value = dict["ENABLELDAP"];
}

Adding to a Dictionary within a dictionary

I am not a particularly confident programmer yet but am getting there.
My problem is that I have a
static Dictionary<string, Dictionary<string, List<string>>> testDictionary = ...
If the Dictionary doesn't contain the current key (string), I can easily add the key and another dictionary that has been populated, like so...
testDictionary.Add(userAgentResult, allowDisallowDictionary);
That works fine, my problem comes when I am trying to add the inner dictionary if the userAgentResult Key already exists.
I was hoping to do it this way...
testDictionary[userAgentResult].Add(allowDisallowDictionary);
but the .Add method wants two arguments, i.e. the string key and list value. So I went on to write this code...
//this list as the dictionary requires a list
List<string> testDictionaryList = new List<string>();
//this method returns a string
testDictionaryList.Add(regexForm(allowResult, url));
//this will add the key and value to the inner dictionary, the value, and then
//add this value at the userAgentKey
testDictionary[userAgentResult].Add(allowDisallowKey, testDictionaryList);
This also works, my problem is that this dictionary is added to numerous times, and when the inner dictionary already contains the key that is trying to be added, it obviously errors. So when
I would probably simplify this by having one dictionary and joining the keys thus "simulating" a grouping.
string key = userAgentResult + allowDisallowKey;
static Dictionary<string, List<string> testDictionary = ...
testDictionary[key] = list;
You simply need to manage one dictionary.
In this case what you need to do is not adding an entry to the inner dictionary. You need to add the value to the key-value pair of the outer dictionary. Only this time the value happens to be yet another dictionary :)
testDictionary[userAgentResult] = allowDisallowDictionary;
Maybe i don't get your problem. First make sure that dictionaries exist like so:
if (!testDictionary.ContainsKey(userAgentResult))
testDictionary[userAgentResult] = new Dictionary<string, List<string>>();
if (!testDictionary[userAgentResult].ContainsKey(allowDisallowKey))
testDictionary[userAgentResult][allowDisallowKey] = new List<string>();
Then you are free to add items like so:
testDictionary[userAgentResult][allowDisallowKey].Add("some value");
testDictionary[userAgentResult][allowDisallowKey].AddRange(someValueList);
When using nested dictionaries i normally use this approach:
private static Dictionary<string, Dictionary<string, List<string>>> _NestedDictionary = new Dictionary<string, Dictionary<string, List<string>>>();
private void DoSomething()
{
var outerKey = "My outer key";
var innerKey = "My inner key";
Dictionary<string, List<string>> innerDictionary = null;
List<string> listOfInnerDictionary = null;
// Check if we already have a dictionary for this key.
if (!_NestedDictionary.TryGetValue(outerKey, out innerDictionary))
{
// So we need to create one
innerDictionary = new Dictionary<string, List<string>>();
_NestedDictionary.Add(outerKey, innerDictionary);
}
// Check if the inner dict has the desired key
if (!innerDictionary.TryGetValue(innerKey, out listOfInnerDictionary))
{
// So we need to create it
listOfInnerDictionary = new List<string>();
innerDictionary.Add(innerKey, listOfInnerDictionary);
}
// Do whatever you like to do with the list
Console.WriteLine(innerKey + ":");
foreach (var item in listOfInnerDictionary)
{
Console.WriteLine(" " + item);
}
}
You need to do the same for the inner dictionary that you did for the outer one. First check if a list already exists for this key. If not create it. Then use the list that either existed or was created.

Is there something like the .NET Dictionary with duplicated keys to fill with a text file?

I have a text file with the following structure
01|value|value|value|value|value|value
02|value|value|value|value|value|value
03A|value|value|value|value|value|value
03A|value|value|value|value|value|value
.
.
N
04|value|value|value|value|value|value
05|value|value|value|value|value|value
06|value|value|value|value|value|value
.
.
N (variable lines)
I tried to read the text file and add it to a dictionary of type <string, string[]> in order to use it like MyDic["01"][0], this is a fragment of the code:
Dictionary<string, string[]> txtFromFile= new Dictionary<string, string[]>();
string strLine;
using (StreamReader sr = new StreamReader(filePath))
{
while ((strLine= sr.ReadLine()) != null)
{
string[] strNodes= strLine.Split('|');
txtFromFile.Add(strNodes[0], strNodes);
}
}
Unfortunately, as you can see, this text file could have duplicated keys like 03A, so I was wondering if there's a collection in c# to achieve this.
NOTE I saw a class named lookup, but there's no constructor for it.
Any thoughts my friends?
What do you suggest?
Thanks!
Why not just create a class like
public class MyLine
{
string key { get;set;}
string[] value {get;set;}
}
and store it in a geneirc List
then you can use linq to query whatever you want ...
You can use the ToLookup extension method:
string[] lines = File.ReadAllLines(filePath);
ILookup<string, string[]> result = lines
.Select(line => line.Split('|'))
.ToLookup(parts => parts[0]);
The first problem is that you are trying to use the wrong type, if you are concerned with multiple entries with the same key. You can achieve this with a List<KeyValuePair<string, string[]>> and your own lookup function, likely through extending the class, or you can add another dictionary inside the dictionary as your value type: Dictionary<string, Dictionary<int, string[]>>. The Dictionary option is the better bet as it has better performance.
How about a List with a custom type?
class KeyValue
{
String ID { get ; set ; }
List<String> Values { get ; private set ;}
(..Constructor etc...)
}
List<KeyValue> myValues = new List<KeyValue>();
while ((strLine= sr.ReadLine()) != null)
{
string[] strNodes= strLine.Split('|');
myValues.Add(new KeyValue(strNodes[0],strNodes));
}
You could use List<KeyValuePair<string, string[]>> or List<Tuple<string, string[]>>
(And of course you might prefer a different collection type instead of List<>)
I'm not sure if you're trying to distinguish between values on the first 03A line from values on the second 03A line, but I think you're looking for a NameValueCollection. NameValueCollections allow you to add multiple values to the same key, and the Add() method should check for pre-existing keys before appending the values/creating a new key/value entry.
There's a good example of the way to use the NameValueCollection at the bottom of that MSDN reference article, so you should be able to use that to determine if it's what you really need.
Another thought would be to use
Dictionary<string, List<string[]>>
Where "string" is the value that might be repeated. When it gets repeated, you create another Dictionary inside. If a row exists once, it will have one List. If a duplicate row is found, add another. In this way, you can see how many duplicate rows there were just by count of Lists.

Best way to Query a Dictionary in C#

I have a dictionary, for example Dictionary<int, string>.
What would be the best way to get the string value if I know the key?
If you know the key is in the dictionary:
value = dictionary[key];
If you're not sure:
dictionary.TryGetValue(key, out value);
What do you mean by best?
This is the standard way to access Dictionary values by key:
var theValue = myDict[key];
If the key does not exist, this will throw an exception, so you may want to see if they key exists before getting it (not thread safe):
if(myDict.ContainsKey(key))
{
var theValue = myDict[key];
}
Or, you can use myDict.TryGetValue, though this required the use of an out parameter in order to get the value.
If you want to query against a Dictionary collection, you can do the following:
static class TestDictionary
{
static void Main() {
Dictionary<int, string> numbers;
numbers = new Dictionary<int, string>();
numbers.Add(0, "zero");
numbers.Add(1, "one");
numbers.Add(2, "two");
numbers.Add(3, "three");
numbers.Add(4, "four");
var query =
from n in numbers
where (n.Value.StartsWith("t"))
select n.Value;
}
}
You can also use the n.Key property like so
var evenNumbers =
from n in numbers
where (n.Key % 2) == 0
select n.Value;
var stringValue = dictionary[key];
Can't you do something like:
var value = myDictionary[i];?
string value = dictionary[key];
Dictionary.TryGetValue is the safest way
or use Dictionary indexer as other suggested but remember to catch KeyNotFoundException
Well I'm not quite sure what you are asking here but i guess it's about a Dictionary?
It is quite easy to get the string value if you know the key.
string myValue = myDictionary[yourKey];
If you want to make use like an indexer (if this dictionary is in a class) you can use the following code.
public class MyClass
{
private Dictionary<string, string> myDictionary;
public string this[string key]
{
get { return myDictionary[key]; }
}
}

Categories