print OrderedDictionary array values? - c#

Line: gets one line from the file, it's iterate
string[] values = line.split(","); // ex: ["hi, "test", "no", "sup"]
OrderedDictionary od = new OrderedDictionary();
Tuple<int, string[]> innerTuple = new Tuple<int, string[]>(int.Parse(value[0], values);
I cannot seem to find a way to print out the value array. However, I can print out the arrays by using regular dictionary (I don't like how dictionary can mix up the order of insertion).

Try with this:
foreach (DictionaryEntry item in od)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
UPDATE:
If you have a string array as the value then you should try something like this:
foreach (DictionaryEntry item in od)
{
if (item.Value is string[])
{
foreach (string str in (string[])item.Value)
{
Console.WriteLine("A string item: " + str);
}
}
}

Related

Read the value of DictionaryEntry object if the value is List<string>

I want to parse my Hashtable using DictionaryEntry and read the value of DictionaryEntry object if the value is List<string>
Below is the sample code.
Hashtable strResx = new Hashtable();
List<string> allDetails = new List<string>();
allDetails.Add("val0");
allDetails.Add("val1");
strResx.Add(1, allDetails);
strResx.Add(2, allDetails);
strResx.Add(3, allDetails);
foreach (DictionaryEntry entry in strResx)
{
string value0 = entry.Value.ToString();
string value1 = entry.Value.ToString();
someFunction(value0, , value1);
}
I am really confused how to do indexing to entry.Value.ToString();
something like entry.Value[0].ToString(); and entry.Value[1].ToString();
Kindly Help.
You can cast value to List<string> type:
foreach (DictionaryEntry entry in strResx)
{
var value = (List<string>)entry.Value;
string value0 = value[0];
string value1 = value[1];
someFunction(value0, value1);
}
You can do this cast automatically in foreach loop if you'll loop through Values insted of entries:
foreach (List<string> value in strResx.Values)
{
string value0 = value[0];
string value1 = value[1];
someFunction(value0, value1);
}
But consider to use generic Dictionary<int,List<string>> instead of Hashtable. That will give you both type-safety (i.e. there will not be dictionary entry with value of type different from List<string>) and strongly-typed keys and values:
var strResx = new Dictionary<int,List<string>>();
// ...
strResx.Add(1, allDetails);
strResx.Add(2, allDetails);
strResx.Add(3, allDetails);
foreach (var kvp in strResx)
{
string value0 = kvp.Value[0];
string value1 = kvp.Value[1];
someFunction(value0, value1);
}
Notes:
You are adding same allDetails list to all hashtable entries
Consider to check whether entry value is not null
Consider to check whether entry value has enough items to avoid IndexOutOfRange exception
In your case you can use something like:
foreach (DictionaryEntry entry in strResx)
{
var list = (List<string>)entry.Value;
string value0 = list[0];
string value1 = list[1];
someFunction(value0, value1);
}

How to iterate over nested dictionaries in c# recursively

I have dictionary variable is like:
Dictionary<string,object> dictionary;
This dictionary has nested dictionaries inside in runtime like:
Dictionary<string,Dictionary<string,Dictionary<....<Dictionary<string,int>>>
I am trying to search for all the keys in these nested dictionaries. It may be possible with recursive but i coudn't handle the recursive case. After string comparisons(string.Contains("searchText") done i am going to keep only contained ones.
How can i achieve this goal?
You can try dfs.. Below code just prints every key
public void NestedDictIteration(Dictionary<string,object> nestedDict)
{
foreach (string key in nestedDict.Keys)
{
Console.WriteLine(key);
object nextLevel = nestedDict[key];
if(nextLevel == null)
{
continue;
}
NestedDictIteration((Dictionary<string, object>)nextLevel);
}
}
You can do like this.
Dictionary<string, Dictionary<string, string>> dict= new Dictionary<string, Dictionary<string, string>>();
var query = from outer in dict
from inner in outer.Value
select outer.Key + "->>" + inner.Key + ", " + inner.Value;
foreach (string item in query)
{
//item
}
Or like this
foreach (string key in dict.Keys)
{
foreach (string innerKey in dict[key].Keys)
{
//dict[key][innerKey];
}
}

How to retrieve all values in dictionary

I have the following Dictionary
public static Dictionary<string, List<int>> termDocumentIncidenceMatrix = new Dictionary<string, List<int>>();
I want to print all values in it , How i can make it ?
I found KeyValuePair but can't recognize in my program ?
Can anyone give me bit of code or link ?
foreach (var term in termDocumentIncidenceMatrix)
{
// Print the string (your key)
Console.WriteLine(term.Key);
// Print each int in the value
foreach (var i in term.Value)
{
Console.WriteLine(i);
}
}
If you want to print all values of the dictionary, you can use:
Dictionary<string, List<int>> dict = new Dictionary<string,List<int>>{{"A",new List<int>{1,2}},{"B",new List<int>{3,4}}};
var integersList = dict.Values.SelectMany(it => it);
foreach (var item in integersList)
{
Console.WriteLine(item);
}

foreach items in hashtable

I need to use Hastable (Not List and not Dictionary), and I have many variables with keys. I add keys and variables to class, and use it in my program. But I don't know how to parse Hashtable. I tried this:
Hashtable toboofer = null;
string path = #"my.bin";
FileStream fin = File.OpenRead(path);
try
{
BinaryFormatter bf = new BinaryFormatter();
toboofer = (Hashtable)bf.Deserialize(fin);
for (int i = 0; i <= toboofer.Count; i++ )
//foreach (KeyValuePair<string, string> kvp in toboofer)
{
myclass cl = new myclass();
cl.Fio = toboofer[i].ToString();
cl.About = toboofer[i].ToString();
}
}
but I have an error. When I try string item or cycle for I have an error too.
Hashtable has DictionaryEntry as collection element
foreach (DictionaryEntry entry in toboofer)
{
// do something
}
Make list of myclass from hashtable:
var listOfMyClass = toboofer.Cast<DictionaryEntry>().
Select(e => new myclass()
{ Fio = e.Key.ToString(), About = e.Value.ToString() });
try this hashtable make use if DictionaryEntry, where KeyValuePair generic used by generic dictionary .Net 2 (and onwards)
Aslo note that Hashtable doesnt have generic version of it and Each element in hastable represented by DictionaryEntry
foreach (DictionaryEntry entry in hashtable)
{
Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
}

Splitting a string value inside list<>

I have a list contained within a dictionary that contains the follwing values
value a
value b
value c
value 1, value 2, value3
value d
the end result I would like is
value a
value b
value c
value 1
value 2
value 3
value d
problem is iterating through the dictionary and trying to change the collection will not work as I am trying to modify it while looping through it
string[] ar;
foreach (var kvp in dict)
{
if (kvp.Key == "STAR-016")
{
foreach (var v in kvp.Value)
{
if (v.Contains(','))
{
ar = v.Split(',');
foreach (var a in ar)
{
kvp.Value.Add(a);
}
}
}
}
}
how can i get the desired result?
Try using LINQ:
var list = new List<string>()
{
"value a",
"value b",
"value 1, value 2, value 3",
"value c"
};
/* THIS IS THE IMPORTANT PART: */
/* Replace list with kvp.Value */
list = list.SelectMany(
i => i.Split( ',' ).Select( v => v.Trim() )
).ToList();
foreach ( var item in list )
Console.WriteLine( item );
Output:
value a
value b
value 1
value 2
value 3
value c
To use this within your code:
foreach (var kvp in dict)
{
if (kvp.Key == "STAR-016")
{
var newList =
kvp.Value.SelectMany(
i => i.Split( ',' ).Select( v => v.Trim() )
);
kvp.Value.Clear();
kvp.Value.AddRange(newList);
}
}
Thanks to #Mudu for pointing out the simpler i => syntax
Assuming that this is just an example and you actually want this not only for a key STAR-016 but for all where the value (which is a List<string>) contains a comma:
Dictionary<string, List<String>> dict = new Dictionary<string, List<String>>();
dict.Add("STAR-016", new List<string>() {
"value a", "value b", "value c", "value 1, value 2, value 3", "value d"
});
foreach (var kvp in dict)
{
for (int i = kvp.Value.Count - 1; i >= 0; i--)
{
string str = kvp.Value[i];
if (str.Contains(','))
{
var parts = str.Split(',').Select(p => p.Trim());
kvp.Value.RemoveAt(i);
kvp.Value.InsertRange(i, parts);
}
}
}
Demo
I'm looping from the end to the start to avoid complications because InsertRange will add new strings which increases the Count.
I'm using RemoveAt to replace the strings with commas with new strings(one for each part splitted by comma) which are added. I'm using InsertRange instead of AddRange because you want to keep the order.
Result:
value a
value b
value c
value 1
value 2
value 3
value d
You should be able to do that with one line using SelectMany.
dict["STAR-016"] = dict["STAR-016"].SelectMany(s=>s.Split(',')).ToList();
This replaces the list for your key with one that splits the string on comma, if the string doesn't contain a comma it just returns the string. You might also consider using StringSplitOptions.RemoveEmptyEntries if you don't want empty strings resulting from consecutive commas.
You can loop trough the List using for instead of foreach and modify items
for (int i = 0; i < kvp.Value.Count; i++)
{
if (kvp.Value[i].Contains(','))
...
}
(edit: juharr's https://stackoverflow.com/a/14875503/17713 does basically the same with build-in LINQ features and in more functional style, which is often more expressive in describing the actual problem)
I'd go for an approach with yield that does not modify the original collection. Here is an example code that operates on a List<string> orig which may also be in a dictionary:
public static void Main()
{
List<string> orig = new List<string>()
{
"value a",
"value b",
"value c",
"value 1, value 2, value 3",
"value d"
};
var result = Flatten(orig).ToList();
foreach(string s in result)
{
Console.WriteLine(s);
}
}
private static IEnumerable<string> Flatten(IList<string> orig)
{
foreach(string s in orig)
{
// split anyway, if there's no colon you just get a one-element
// array containing s, see
// http://msdn.microsoft.com/en-us/library/b873y76a.aspx
foreach(string v in s.Split(','))
{
yield return v.Trim();
}
}
}
In a dictionary, you could then replace the result with the original value:
dict["STAR-016"] = Flatten(dict["STAR-016"]).ToList()
Side note: The above code finds STAR-016 directly rather than using a foreach which is slower. If you did not shorten the code and you're actually just looking up STAR-016 I'd recommend you to use this way of dictionary lookup.

Categories