How to print contents of an hash table? - c#

I've an hash table with the details as mentioned below
public void get_Unique_Sequence(List<string> name, List<List<string>> nameSequence)
{
Hashtable test = new Hashtable();
test.Add(nameSequence, name)
foreach (DictionaryEntry entry in test)
{
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
I'm trying to print the contents of the hash table with the help of foreach loop. However the output which I'm getting is
output:
System.Collections.Generic.List`1[System.String]: System.Collections.Generic.List`1[System.String]
Please guide me to get the key and value (that is the contents) of the hashtable.

You probably don't want to insert the lists objects in the hash table, but the elements in the list.
So first you have to do something like:
(assuming that the list are not null and have the same size)
for(int i =0;i<name.Count;i++){
test.Add(nameSequence[i], name[i]);
}
instad of:
test.Add(nameSequence, name);
And then your method should work.

I don't know how you would like to format the output, but to print the content of a List you have to iterate on it.
On the List of lists you need to iterate two times.
Maybe a solution could be this:
public void get_Unique_Sequence(List<string> name, List<List<string>> nameSequence)
{
Hashtable test = new Hashtable();
test.Add(nameSequence, name);
foreach (DictionaryEntry entry in test)
{
string key = string.Empty;
foreach (string s in (List<string>)entry.Key)
{
key += s + " ";
}
foreach (List<string> list in (List<List<string>>)entry.Value)
{
string value = string.Empty;
foreach (string s in list)
{
value += s + " ";
}
Console.WriteLine("{0}: {1}", key, value);
}
}
}
Of course, you need to format the output according to your needs.

Well, the issue isn't about printing the hashtable. It's about printing a List<List<string>>.
You want something like this for each key and value:
foreach (var sublist in result)
{
foreach (var obj in sublist)
{
Console.WriteLine(obj);
}
}

Related

loading data from csv file into key and value dictionary list

I have a file consisting of a list of text which looks as follows:
Example csv file
There csv file has consist of 3 columns. The first columns will always be the length of 5. So I want to loop through the file content, store those first 5 letters as Key and remaining column as value. I am removing comma between them and Substringing as follows to store.
static string line;
static Dictionary<string, string> stations = new Dictionary<string, string>();
static void Main(string[] args)
{
// Dictionary<string, List<KeyValuePair<string, string>>> stations = new Dictionary<string, List<KeyValuePair<string, string>>>();
var lines = File.ReadAllLines(".\\ariba_sr_header_2017122816250.csv");
foreach (var l in lines)
{
line = l.Replace(",", "");
stations.Add(line.Substring(14),line.Substring(14, line.Length-14));
}
//read all key and value in file
foreach (KeyValuePair<string, string> item in stations)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
Console.ReadLine();
}
After debug, the output is
Output
My Expected Result is as follow:
Expected Result
I cannot see any KeyValuePair here. You have
00021,00014,Ordered
00021,00026,Ordered
00024,00036,Ordered
...
and you want
00021
00021
00024
000014Ordered
000026Ordered
000036Ordered
...
outcome which seems to be IEnumerable<string>. You can try Linq for this
var result = File
.ReadLines(".\\ariba_sr_header_2017122816250.csv")
.Line(line => line.Split(','))
.SelectMany(items => new string[] {
items[0],
$"0{items[1]}{items[2]}" })
.OrderBy(item => item.Length);
foreach (var item in result)
Console.WriteLine(item);
Here we Split each line like 00021,00014,Ordered into separate items: {00021, 00014, Ordered}anf then combine them back with a help ofSelectMany`. We want
00021 which is items[0]
000014Ordered which is 0 + items[1] + items[2]
Finally we want to have short items first - OrderBy(item => item.Length)
Here you go:
var stations = new Dictionary<string, string>();
var lines = File.ReadAllLines(#"C:\temp\22.txt");
foreach (var l in lines)
{
var lsplit = l.Split(',');
if (lsplit.Length > 1)
{
var newkey = lsplit[0];
var newval = lsplit[1] + lsplit[2];
stations[newkey] = newval;
}
}
//read all key and value in file
foreach (KeyValuePair<string, string> item in stations)
{
Console.WriteLine(item.Key + " = " + item.Value);
}
Console.ReadLine();
Not exactly the output you expected, but hopefully it helps.

Unable to find value by key in dictionary in case of comma separated key

I have a dictionary like below where i store list of file names with key generated as Csv1,Csv2 based on number of files.
I have a string array like below :
string[] files = { "SampleCSVFile_5300kb1.csv,SampleCSVFile_5300kb2.csv", "SampleCSVFile_5300kb3.csv"};
int counter=1;
var dictionary = new Dictionary<string, string>();
foreach (var file in files)
{
dictionary.Add("CSV" + counter, file);
counter++;
}
foreach (var file in files)
{
string myValue;
if (dictionary.TryGetValue(file, out myValue)) // getting null in out value
}
When i try to search for SampleCSVFile_5300kb1.csv i am getting null in my myValue variable.
Screenshot:
Update:i realize that i was adding wrong key so changed it like below but still unable to find CSV1 in case of SampleCSVFile_5300kb1.csv:
foreach (var file in files)
{
dictionary.Add(file,"CSV" + counter);
counter++;
}
Based on the comment you said in Amir Popoviches answer. I think you should alter your dictionary construction.
So you will create a mapping from each of the .csv file(s) to the "CSV1" etc string.
var files = new[] { "SampleCSVFile_5300kb1.csv,SampleCSVFile_5300kb2.csv", "SampleCSVFile_5300kb3.csv" };
var counter = 1;
var dictionary = new Dictionary<string, string>();
foreach (var file in files)
{
if (string.IsNullOrWhiteSpace(file))
{
continue;
}
foreach (var item in file.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
{
dictionary.Add(item, "CSV" + counter);
}
counter++;
}
And as you said in comments you want to find what "CSVX" file is for each of the files you have so we simulate you trying to find a match for these files. Notice that this array has all separate file names, in the upper array we had values comma separated so we group them together.
var files2 = new[] { "SampleCSVFile_5300kb1.csv", "SampleCSVFile_5300kb2.csv", "SampleCSVFile_5300kb3.csv" };
foreach (var file in files2)
{
string csvValue;
if (dictionary.TryGetValue(file, out csvValue))
{
Console.WriteLine("{0} -> {1}", file, csvValue);
}
}
This should output you
SampleCSVFile_5300kb1.csv -> CSV1
SampleCSVFile_5300kb2.csv -> CSV1
SampleCSVFile_5300kb3.csv -> CSV2
First argument in TryGetValue is key. So you should pass there "CSV" + counter to make it works.
https://msdn.microsoft.com/pl-pl/library/bb347013(v=vs.110).aspx
You are adding items to the dictionary with the following keys:
"CSV" + counter -> CSV1, CSV2...
And you are trying to find different values (e.g. "SampleCSVFile_5300kb1.csv,SampleCSVFile_5300kb2.csv") here:
foreach (var file in files)
{
string myValue;
if (dictionary.TryGetValue(file, out myValue)) // getting null in out value
}
Try below updated code:
string[] files = { "SampleCSVFile_5300kb1.csv,SampleCSVFile_5300kb2.csv", "SampleCSVFile_5300kb3.csv" };
int counter = 1;
var dictionary = new Dictionary<string, string>();
foreach (var file in files)
{
dictionary.Add("CSV" + counter, file);
counter++;
}
counter = 1;
foreach (var file in files)
{
string myValue;
//You need to pass key name here but you are passing value of it
//Need to update here
string keyName = "CSV" + counter;
if (dictionary.TryGetValue(keyName, out myValue)) ; // getting null in out value
counter++;
}
Iterate the dictionary an find your desired value using split by comma. you will get "SampleCSVFile_5300kb1.csv" and "SampleCSVFile_5300kb2.csv" into the fileName array for the same myvalKey
foreach (KeyValuePair<string, string> entry in dictionary)
{
string myvalKey = entry.Key;
string myval = entry.Value;
if (myval.Contains(',')) {
string[] fileNames = myval.Split(',');
}
}
From what I understand you seem to be looking for a way to match only part of a key. And while I suggest using the answers of Janne Matikainen and just add the parts of your key separately with the same value, regardless I will give you a way to match on a partial key using a bit of Linq.
string resultValue = null;
string resultKey = dictionary.Keys.FirstOrDefault(k => k.Contains(file));
if(resultKey != null)
resultValue = dictionary[resultKey];
this does assume only the first match is wanted, if you want all matching keys replace FirstOrDefault with Where.
Beware that while this code is easy it is not suitable for when performance is critical as you iterate over the keys basically using the dictionary as a
List<Tuple<string,string>>

C# how write the whole array if string contains keyword

I am searching if a string within an stringarray contains a keyword.
If a string gets a match i want the array(s) which the string was found in to be output on the console.
Sofar i have managed to output every string that contains a keyword within the stringarray.
I have tried to work around this by outputting the array insteed but then i get this message "System.String[]"
However, that is not my intent. I wanted the array to be displayed. I wonder, how can i do this?
//Sorry for bad english.
Here are the relevant parts from my code:
List<string[]> loggbok = new List<string[]> { };
string[] log = new string[3]; //date, title, post
DateTime date = DateTime.Now;
log[0] = "\n\tDate: " + date.ToLongDateString() + " Time: " + date.ToShortTimeString();
Console.Write("\tTitle: ");
log[1] = "\tTitle: " + Console.ReadLine();
Console.Write("\tPost: ");
log[2] = "\tPost: " + Console.ReadLine();
loggbok.Add(log);
log = new string[3];
Console.Write("\n\tSearch: ");
string keyWord;
keyWord = Console.ReadLine();
foreach (string[] item in loggbok)
{
foreach (var s in item)
{
if (s.Contains(keyWord))
{
Console.WriteLine(item);
}
}
}`enter code here`
For displaying the whole array try this:
Console.WriteLine(String.Join("\r\n", item));
You can filter the array like this:
Console.WriteLine(String.Join("\r\n", item.Where(item => item.Contains(keyWord)).ToArray());
or
string[] filtered = item.Where(s => s.Contains(keyWord)).ToArray();
Console.WriteLine(String.Join("\r\n", filtered));
If you want to filter the whole loggbok (list of string arrays) use the SelectMany extension.
string[] filtered = loggbok.SelectMany(s => s.Contains(keyWord)).ToArray();
Console.WriteLine(String.Join("\r\n", filtered));
If I understand your question correctly, you want the whole array in which the keyword has been found.
What you do wrong is you state Console.WriteLine(item) which will only print that item.
Instead, make a function which returns true if the keyword has been found in this array and false if this has not happened. Your code would look something like this:
string keyWord;
keyWord = Console.ReadLine();
foreach (string[] item in loggbok)
{
if (checkItem(item)) {
for(int i = 0; i < item.Length; i++){
Console.WriteLine(item[i]);
}
}
}
public bool checkItem(string[] item, string keyWord) {
foreach(var s in item) {
if(s.Contains(keyWord))
return true;
}
return false;
}
This might help you.

How to convert string to list<string> type

foreach (string Tablename in uniqueFields)
{
List<string> TblName = Tablename;//here the problem
TblName = new List<string>();
Console.WriteLine("children of :" + TblName);
foreach (string TableAssociatedValue in fields)
{
if (TableAssociatedValue.Contains(Tablename.Trim()))
{
Console.WriteLine(TableAssociatedValue);
}
}
}
No need to use List<string> in your case. Just use Tablename directly since it contains what is required:
foreach (string Tablename in uniqueFields)
{
// not required List<string> TblName = Tablename;//here the problem
// doesn't make sense, and is not required TblName = new List<string>();
//Console.WriteLine("children of :" + TblName); // use the line below instead
Console.WriteLine("children of :" + Tablename);
foreach (string TableAssociatedValue in fields)
{
if (TableAssociatedValue.Contains(Tablename.Trim()))
{
Console.WriteLine(TableAssociatedValue);
}
}
}
Where you confused by uniqueFields which could be a List<string>? Don't be: the foreach construct is already enumerating each string in your list and will return each one as a string assigned to Tablename inside the loop. As a consequence you are not anymore required to work with the List itself, you can directly use Tablename as string.
you can assign as
List<string> TblName=new List<string>{Tablename};
You cannot set a list List<string> to a string - you have to add the string to the list
List<string> TblName=new List<string>{Tablename};
But you are setting TblName to an empty list just after, which makes no sense.
foreach (string Tablename in uniqueFields)
{
List<string> TblName = new List<string>();
// <Start Changes>
TblName.Add(Tablename);
// <End Changes>
Console.WriteLine("children of :" + TblName);
foreach (string TableAssociatedValue in fields)
{
if (TableAssociatedValue.Contains(Tablename.Trim()))
{
Console.WriteLine(TableAssociatedValue);
}
}
}
As already mentioned, you cannot assign a value of type string to a value of type List<String>. How do you think should this even be possible?

How to swap Hashtable's key with Value

I have solved it by following.
Since it is long, i need a better one.
//Code
class Program
{
static void Main(string[] args)
{
Hashtable hsTbl = new Hashtable();
hsTbl.Add(1, "Suhas");
hsTbl.Add(2, "Madhuri");
hsTbl.Add(3, "Om");
List<object> keyList = new List<object>();
List<object> ValList = new List<object>();
Console.WriteLine("Key Value");
foreach (DictionaryEntry item in hsTbl)
{
Console.WriteLine(item.Key + " " + item.Value);
keyList.Add(item.Value);
ValList.Add(item.Key);
}
hsTbl.Clear()
//Swapping
for (int i = 0; i < keyList.Count; i++)
{
hsTbl.Add(keyList[i], ValList[i]);
}
//will display hashtable after swapping
foreach (DictionaryEntry item in hsTbl)
{
Console.WriteLine(item.Key + " " + item.Value);
}
}
}
Is there any other better solution?
You could do it slightly simpler using an additional array and the CopyTo method rather than 2 lists but without creating an additional HashTable as follows:
//Code
using System;
using System.Collections;
class Program
{
static void Main()
{
Hashtable hsTbl = new Hashtable();
hsTbl.Add(1, "Suhas");
hsTbl.Add(2, "Madhuri");
hsTbl.Add(3, "Om");
DictionaryEntry[] entries = new DictionaryEntry[hsTbl.Count];
hsTbl.CopyTo(entries, 0);
hsTbl.Clear();
foreach(DictionaryEntry de in entries) hsTbl.Add(de.Value, de.Key);
// check it worked
foreach(DictionaryEntry de in hsTbl)
{
Console.WriteLine("{0} : {1}", de.Key, de.Value);
}
}
}
Note that, in general, no method is guaranteed to work because some of the values in the original hashtable may be duplicated and therefore be unsuitable as keys.
You can use generic Dictionary<string,int>, which is easy to create with Linq:
var dictionary = hsTbl.OfType<DictionaryEntry>()
.ToDictionary(e => (string)e.Value, e => (int)e.Key);
If you really need Hashtable, then:
Hashtable table = new Hashtable();
foreach (DictionaryEntry entry in hsTbl)
table.Add(entry.Value, entry.Key);
But make sure that all values are unique, if you want to swap value and key.

Categories

Resources